HDU-3085-Nightmare Ⅱ(双向BFS)

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

Author

二日月

Source

HDU 2nd “Vegetable-Birds
Cup” Programming Open Contest

思路:鬼分身所在的地方就直接变成墙,接着女孩走1步,男孩走3步,相遇就直接返回时间。(注意:鬼的分身也是可以继续分的)

#include <stdio.h>
#include <string.h>

struct{
int x,y,step;
}que1[1000000],que2[1000000],que[1000000],t;

int n,m,gxa,gya,gxb,gyb,xa,ya,xb,yb,nxt[4][2]={{0,1},{1,0},{0,-1},{-1,0}},top,bottom,gt;
char mp[800][805];
bool vis1[800][800],vis2[800][800],vis[800][800];

void divide()//鬼分身,让有鬼的地方都变成墙
{
    int i;

    while(top<bottom)
    {
        t=que[top];

        if(t.step>=gt) return;

        t.step++;

        for(i=0;i<4;i++)
        {
            t.x+=nxt[i][0];
            t.y+=nxt[i][1];

            if(t.x>=0 && t.x<n && t.y>=0 && t.y<m && !vis[t.x][t.y])
            {
                vis[t.x][t.y]=1;

                mp[t.x][t.y]='X';

                que[bottom++]=t;
            }

            t.x-=nxt[i][0];
            t.y-=nxt[i][1];
        }

        top++;
    }
}

int bfs()
{
    int i,t1,t2,top1,top2,bottom1,bottom2;

    memset(vis,0,sizeof vis);
    memset(vis1,0,sizeof vis1);
    memset(vis2,0,sizeof vis2);

    top=0;
    bottom=2;
    que[0].x=gxa;
    que[0].y=gya;
    que[0].step=0;
    que[1].x=gxb;
    que[1].y=gyb;
    que[1].step=0;

    gt=2;
    t1=1;
    t2=3;

    top1=0;
    bottom1=1;
    que1[0].x=xa;
    que1[0].y=ya;
    que1[0].step=0;
    vis1[xa][ya]=1;

    top2=0;
    bottom2=1;
    que2[0].x=xb;
    que2[0].y=yb;
    que2[0].step=0;
    vis2[xb][yb]=1;

    while(1)
    {
        divide();//鬼先分身

        bool flag=0;

        while(top1<bottom1)//女孩走
        {
            t=que1[top1];

            if(t.step>=t1) break;

            t.step++;

            for(i=0;i<4;i++)
            {
                t.x+=nxt[i][0];
                t.y+=nxt[i][1];

                if(t.x>=0 && t.x<n && t.y>=0 && t.y<m && mp[t.x-nxt[i][0]][t.y-nxt[i][1]]!='X' && mp[t.x][t.y]!='X' && !vis1[t.x][t.y])
                {
                    flag=1;

                    if(vis2[t.x][t.y]) return t1;

                    vis1[t.x][t.y]=1;
                    que1[bottom1++]=t;
                }

                t.x-=nxt[i][0];
                t.y-=nxt[i][1];
            }

            top1++;
        }

        while(top2<bottom2)//男孩走
        {
            t=que2[top2];

            if(t.step>=t2) break;

            t.step++;

            for(i=0;i<4;i++)
            {
                t.x+=nxt[i][0];
                t.y+=nxt[i][1];

                if(t.x>=0 && t.x<n && t.y>=0 && t.y<m && mp[t.x-nxt[i][0]][t.y-nxt[i][1]]!='X' && mp[t.x][t.y]!='X' && !vis2[t.x][t.y])
                {
                    flag=1;

                    if(vis1[t.x][t.y]) return t1;

                    vis2[t.x][t.y]=1;
                    que2[bottom2++]=t;
                }

                t.x-=nxt[i][0];
                t.y-=nxt[i][1];
            }

            top2++;
        }

        if(!flag) return -1;

        gt+=2;
        t1++;
        t2+=3;
    }
}

int main()
{
    int T,i,j,cnt;

    scanf("%d",&T);

    while(T--)
    {
        scanf("%d%d",&n,&m);

        for(i=0;i<n;i++) scanf("%s",mp[i]);

        cnt=0;

        for(i=0;i<n;i++) for(j=0;j<m;j++)
        {
            if(mp[i][j]=='G') xa=i,ya=j;
            else if(mp[i][j]=='M') xb=i,yb=j;
            else if(mp[i][j]=='Z')
            {
                mp[i][j]='X';

                if(!cnt) gxa=i,gya=j;
                else gxb=i,gyb=j;

                cnt++;
            }
        }

        printf("%d\n",bfs());
    }
}
时间: 2024-10-25 06:31:37

HDU-3085-Nightmare Ⅱ(双向BFS)的相关文章

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

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 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

HDU 1242 -Rescue (双向BFS)&amp;&amp;( BFS+优先队列)

题目链接:Rescue 进度落下的太多了,哎╮(╯▽╰)╭,渣渣我总是埋怨进度比别人慢...为什么不试着改变一下捏.... 开始以为是水题,想敲一下练手的,后来发现并不是一个简单的搜索题,BFS做肯定出事...后来发现题目里面也有坑 题意是从r到a的最短距离,"."相当时间单位1,"x"相当时间单位2,求最短时间 HDU 搜索课件上说,这题和HDU1010相似,刚开始并没有觉得像剪枝,就改用  双向BFS   0ms  一Y,爽! 网上查了一下,神牛们竟然用BFS+

HDU 1242 -Rescue (双向BFS)&amp;amp;&amp;amp;( BFS+优先队列)

题目链接:Rescue 进度落下的太多了,哎╮(╯▽╰)╭,渣渣我总是埋怨进度比别人慢...为什么不试着改变一下捏.... 開始以为是水题,想敲一下练手的,后来发现并非一个简单的搜索题,BFS做肯定出事...后来发现题目里面也有坑 题意是从r到a的最短距离,"."相当时间单位1,"x"相当时间单位2,求最短时间 HDU 搜索课件上说,这题和HDU1010相似,刚開始并没有认为像剪枝,就改用  双向BFS   0ms  一Y,爽! 网上查了一下,神牛们居然用BFS+优

HDU3085 Nightmare Ⅱ (双向BFS)

联赛前该练什么?DP,树型,状压当然是爆搜啦 双向BFS就是两个普通BFS通过一拼接函数联系,多多判断啦 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #define R(a,b,c) for(register int a = (b); a <= (c); ++a) #define nR(a,b,c

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)

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

HDU 1043 Eight(双向BFS+康托展开)

http://acm.hdu.edu.cn/showproblem.php?pid=1043 题意:给出一个八数码,求出到达指定状态的路径. 思路:路径寻找问题.在这道题里用到的知识点挺多的.第一次用双向BFS来做. ①双向BFS 在单向BFS的基础上,多建一个从终止状态开始搜索的队列,当然这个时候需要两个vis[]辅助数组,分别记录两个队列的访问情况,当两个队列相遇时即可终止循环. ②康托展开 X=a[n]*(n-1)!+a[n-1]*(n-2)!+...+a[i]*(i-1)!+...+a[

HDU 1195 Open the Lock 双向BFS

题目链接:Open the Lock 题意:就是给定两个4位数,起始,结束.问从起始数字到达结束数字 最少变换多少步,每个数 可以+1 / -1 或交换位置,都算做是一步. 单广,双广都用了,感觉双向BFS,太棒了,HDU的这个题双向BFS时间优化的太棒了 有图,有真相! 时间优化了近9倍... PS:今天还学习一个sscanf函数,挺棒的 单搜的代码就不贴了,贴个双搜的 #include<cstdio> #include <iostream> #include<cstrin