HDU 3085 Nightmare Ⅱ【BFS +曼哈顿距离+综合性较强】

Nightmare Ⅱ

Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 16   Accepted Submission(s) : 6

Font: Times New Roman | Verdana | Georgia

Font Size: ← →

Problem Description

Last night, little erriyue had a horrible nightmare. He dreamed that he and his girl friend were trapped in a big maze separately. More terribly, there are two ghosts in the maze. They will kill the people. Now little erriyue wants to know if he could find
his girl friend before the ghosts find them.

You may suppose that little erriyue and his girl friend can move in 4 directions. In each second, little erriyue can move 3 steps and his girl friend can move 1 step. The ghosts are evil, every second they will divide into several parts to occupy the grids
within 2 steps to them until they occupy the whole maze. You can suppose that at every second the ghosts divide firstly then the little erriyue and his girl friend start to move, and if little erriyue or his girl friend arrive at a grid with a ghost, they
will die.

Note: the new ghosts also can devide as the original ghost.

Input

The input starts with an integer T, means the number of test cases.

Each test case starts with a line contains two integers n and m, means the size of the maze. (1<n, m<800)

The next n lines describe the maze. Each line contains m characters. The characters may be:

‘.’ denotes an empty place, all can walk on.

‘X’ denotes a wall, only people can’t walk on.

‘M’ denotes little erriyue

‘G’ denotes the girl friend.

‘Z’ denotes the ghosts.

It is guaranteed that will contain exactly one letter M, one letter G and two letters Z.

Output

Output a single integer S in one line, denotes erriyue and his girlfriend will meet in the minimum time S if they can meet successfully, or output -1 denotes they failed to meet.

Sample Input

3
5 6
XXXXXX
XZ..ZX
XXXXXX
M.G...
......
5 6
XXXXXX
XZZ..X
XXXXXX
M.....
..G...

10 10
..........
..X.......
..M.X...X.
X.........
.X..X.X.X.
.........X
..XX....X.
X....G...X
...ZX.X...
...Z..X..X

Sample Output

1
1
-1
#include<stdio.h>
#include<queue>
#include<math.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
char map[810][810];
int step[4][2]= {1,0,-1,0,0,1,0,-1};
struct node
{
    int x,y;
} M,G,Z[2];
int num_of_step,n,m;
queue<node> q[3];

bool ghost(node a)
{
    for(int i=0; i<2; i++)
    {
        if(abs(a.x-Z[i].x)+abs(a.y-Z[i].y) <= 2*num_of_step)//
            return false;//被抓
    }
    return true;
}

bool check(node b)
{
    if(b.x>=0&&b.y>=0&&b.x<n&&b.y<m&&map[b.x][b.y]!='X')
        return true;
    return false;
}

bool BFS(int people,int time,int start,int endd)
{
    node cur,next;
    q[2]=q[people];

    for(int i=0; i<time; i++)
    {
        while(!q[2].empty())
        {
            cur=q[2].front();
            q[2].pop();
            q[people].pop();
            if(ghost(cur))  //如果被抓
            {
                for(int i=0; i<4; i++)
                {
                    next=cur;
                    next.x+=step[i][0];
                    next.y+=step[i][1];
                    if(ghost(next)&&check(next)&&map[next.x][next.y]!=start)
                    {
                        if(map[next.x][next.y]==endd)
                            return true;
                        map[next.x][next.y]=start;
                        q[people].push(next);
                    }
                }
            }
        }
        q[2]=q[people];
    }
    return false;
}

int solve ()
{

    for(int i=0; i<3; i++) ////clear
    {
        while(!q[i].empty())
            q[i].pop();
    }
    num_of_step=0;
    q[0].push(M);
    q[1].push(G);
    while(!q[0].empty()&&!q[1].empty())////
    {
        num_of_step++;
        if(BFS(0,3,'M','G')||BFS(1,1,'G','M'))////
            return num_of_step;
    }
    return -1;
}

int main (void)
{
    int N;
    scanf("%d",&N);
    while(N--)
    {
        int cnt=0;
        scanf("%d%d",&n,&m);
        //getchar();
        for(int i=0; i<n; i++)
        {
            scanf("%s",map[i]);
            for(int ii=0; ii<m; ii++)
            {
                if(map[i][ii]=='M')      M.x=i,M.y=ii;
                else if(map[i][ii]=='G') G.x=i,G.y=ii;
                else if(map[i][ii]=='Z') Z[cnt].x=i,Z[cnt].y=ii,++cnt;
            }
        }
        //getchar();
        printf("%d\n",solve());
    }
    return 0;
}
..X.......
..M.X...X.
X.........
.X..X.X.X.
.........X
..XX....X.
X....G...X
...ZX.X...
...Z..X..X

Sample Output

1
1
-1
时间: 2024-10-04 09:09:50

HDU 3085 Nightmare Ⅱ【BFS +曼哈顿距离+综合性较强】的相关文章

HDU 3085 Nightmare Ⅱ (双向广搜)

题意:有M,G两人和鬼魂(Z)在n*m的方格内,M每秒走3步,G每秒走一步,鬼魂每秒走2步,问是否能 不遇到鬼魂下两人相遇,鬼魂可以穿墙(X),人不可以.初始鬼魂有2个. #include<stdio.h> #include<string.h> #include<string> #include<queue> #include<map> #include<iostream> #include<algorithm> #def

HDU 3085 - Nightmare Ⅱ - []

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3085 Problem DescriptionLast night, little erriyue had a horrible nightmare. He dreamed that he and his girl friend were trapped in a big maze separately. More terribly, there are two ghosts in the maze.

hdu 1072 Nightmare BFS,第一次刷BFS的题,感好牛逼的。。。

Nightmare Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7758    Accepted Submission(s): 3723 Problem Description Ignatius had a nightmare last night. He found himself in a labyrinth with a ti

HDU 1072 Nightmare BFS

其实就是多加了一个引爆时间的限制条件,反正n,m给的很小,直接记录3维状态,之后就很随意了. #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <set> #include <vector> #include <string> #include <queue> #include <deque&g

HDU 4311&amp;4312 Meeting point-1&amp;2 (曼哈顿距离&amp;&amp;切比雪夫距离)

HDU 4311 题意:平面上有n个点,一个点(x,y)只能到达(x-1,y), (x+1,y), (x, y-1), (x, y+1)4个点.从n个点中找到一点,使其他点到此点的距离之和最小. 思路: 可以发现,两个点间距离为 |x1-x2| + |y1-y2| ,这便是两点间的曼哈顿距离. 朴素的做法是遍历所有点,枚举该点与其他点间的曼哈顿距离之和,但是会TLE: 取巧的做法是将所有点与中心点的曼哈顿距离排序,枚举中间大概250个点左右的情况比较即可(不要欺负人家数据水! 正确姿势: 用结构

Hdu 4312-Meeting point-2 切比雪夫距离,曼哈顿距离,前缀和

题目: http://acm.hdu.edu.cn/showproblem.php?pid=4312 Meeting point-2 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1231    Accepted Submission(s): 691 Problem Description It has been ten years s

Hdu 4311-Meeting point-1 曼哈顿距离,前缀和

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4311 Meeting point-1 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3426    Accepted Submission(s): 1131 Problem Description It has been ten years s

HDU 1072 Nightmare (BFS)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1072 题目大意: 走迷宫,初始剩余时间为6min,每步1min:到reset区是若剩余时间大于0,则可以重置.到终点3区,若时间大于0,则成功逃脱.(可以走回路) 0:wall 1:可以走 2:起点 3:终点 4:剩余时间重置为6 源代码: #include<iostream> #include<cstring> #include<cstdio> #include<q

kuangbin专题 专题二 搜索进阶 Nightmare Ⅱ HDU - 3085

题目链接:https://vjudge.net/problem/HDU-3085 题意:有两个鬼和两个人和墙,鬼先走,人再走,鬼每走过的地方都会复制一个新鬼, 但新鬼只能等待旧鬼走完一次行程之后,下一次旧鬼再次开始新的行程时旧鬼才能移动, 旧鬼一个行程能走最多两步,M能走三步,G能走一步. 问M和G能不能在被鬼抓住之前相遇,求最短时间. ‘Z’表示鬼. 第一次用曼哈顿距离来真正解决搜索,参考过别人的代码,这份代码感觉还是比较清楚和简单的. 人每次移动一个距离都要进行一次曼哈顿距离的判断,判断人到