HDU 2216 Game III(BFS)

Problem Description

Zjt and Sara will take part in a game, named Game III. Zjt and Sara will be in a maze, and Zjt must find Sara. There are some strang rules in this maze. If Zjt move a step, Sara will move a step in opposite direction.
Now give you the map , you shold find out the minimum steps, Zjt have to move. We say Zjt meet Sara, if they are in the same position or they are adjacent .
Zjt can only move to a empty position int four diraction (up, left, right, down). At the same time, Sara will move to a position in opposite direction, if there is empty. Otherwise , she will not move to any position.
The map is a N*M two-dimensional array. The position Zjt stays now is marked Z, and the position, where Sara stays, is marked E.

>  . : empty position
>  X: the wall
>  Z: the position Zjt now stay
>  S: the position Sara now stay

Your task is to find out the minimum steps they meet each other.

Input

The input contains several test cases. Each test case starts with a line contains three number N ,M (2<= N <= 20, 2 <= M <= 20 ) indicate the size of the map. Then N lines follows, each line contains M character. A Z and a S will be in the map as the discription above.

Output

For each test case, you should print the minimum steps. “Bad Luck!” will be print, if they can‘t meet each other.

Sample Input

4 4

XXXX

.Z..

.XS.

XXXX

4 4

XXXX

.Z..

.X.S

XXXX

4 4

XXXX

.ZX.

.XS.

XXXX

Sample Output

1

1

Bad Luck!

题解:这个BFS很有意思,跟典型的题目不同,它的目标点在动。当Z在移动的时候,S会往相反方向移动(如果能动)。就是这点,导致WA了两次,vis数组只开了二维来记录Z有没有走过,然后看了题解是要开四维数组,保存Z、S。然后第三组样例又一只跑不出来,发现要把判断是否访问语句放到判断S是否移动的后面才行。

#include <cstdio>
#include <iostream>
#include <string>
#include <sstream>
#include <cstring>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <map>
#define PI acos(-1.0)
#define ms(a) memset(a,0,sizeof(a))
#define msp memset(mp,0,sizeof(mp))
#define msv memset(vis,0,sizeof(vis))
using namespace std;
//#define LOCAL
int n,m;
char mp[22][22];
bool vis[22][22][22][22];
int dir[4][2]={{1,0},{-1,0},{0,-1},{0,1}};
struct Node
{
    int zx,zy;
    int sx,sy;
    int step;
}t,nn;
int bfs()
{
    queue<Node> q;
    while(!q.empty())q.pop();
    vis[t.zx][t.zy][t.sx][t.sy]=1;
    t.step=0;
    q.push(t);
    while(!q.empty())
    {
        t=q.front(),q.pop();
        if(t.sx==t.zx&&abs(t.sy-t.zy)==1)return t.step;
        if(t.sy==t.zy&&abs(t.sx-t.zx)==1)return t.step;
        if(t.sx==t.zx&&t.sy==t.zy)return t.step;
        for(int i=0;i<4;i++)
        {
            nn.zx=t.zx+dir[i][0];
            nn.zy=t.zy+dir[i][1];
            if(mp[nn.zx][nn.zy]==‘X‘)continue;
            if(nn.zx<0||nn.zx>=n||nn.zy<0||nn.zy>=m)continue;
            nn.sx=t.sx-dir[i][0];
            nn.sy=t.sy-dir[i][1];
            if(nn.sx<0||nn.sx>=n||nn.sy<0||nn.sy>=m)nn.sx=t.sx,nn.sy=t.sy;
            if(mp[nn.sx][nn.sy]==‘X‘)nn.sx=t.sx,nn.sy=t.sy;
            nn.step=t.step+1;
            if(vis[nn.zx][nn.zy][nn.sx][nn.sy])continue;
            vis[nn.zx][nn.zy][nn.sx][nn.sy]=1;
            q.push(nn);
        }
    }
    return -1;
}
int main()
{
#ifdef LOCAL
    freopen("in.txt", "r", stdin);
#endif // LOCAL
    ios::sync_with_stdio(false);
    while(cin>>n>>m)
    {
        msv;
        for(int i=0;i<n;i++)cin>>mp[i];
        for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            if(mp[i][j]==‘Z‘)t.zx=i,t.zy=j;
            else if(mp[i][j]==‘S‘)t.sx=i,t.sy=j;
        }
        int ans=bfs();
        if(ans==-1)printf("Bad Luck!\n");
        else printf("%d\n",ans);
    }
    return 0;
}
时间: 2024-10-19 09:44:51

HDU 2216 Game III(BFS)的相关文章

hdu - 2216 Game III &amp;&amp; xtu 1187 Double Maze (两个点的普通bfs)

http://acm.hdu.edu.cn/showproblem.php?pid=2216 zjt和sara在同一个地图里,zjt要去寻找sara,zjt每移动一步sara就要往相反方向移动,如果他们相邻或者在同一个格子里就算相遇. 输出最少步数.注意zjt每次必须要有能移动的点才移动,否则不能移动,但是sara没有能移动的点的话可以呆着不动. 用结构体保存两个点和相应的步数作为一个状态,然后用哈希函数映射出每一个状态的的哈希值,放入set中,判重. 注意哈希函数的选取要确保不能重复. 1 #

hdu 2216 Game III

网上查了标记路径的方法之后就是一道普通的搜索题了,自己还是想不到关键的,努力! #include <stdio.h> #include <string.h> #include <iostream> #include <algorithm> #include <vector> #include <queue> #include <stack> #include <set> #include <map>

hdu 1429 状压bfs

#include <iostream> #include <cstring> #include <string> #include <cstdio> #include <cmath> #include <algorithm> #include <vector> #include <queue> #include <map> #define inf 0x3f3f3f3f #define ll __in

HDU 1242 Rescue(优先队列+bfs)

题目地址:HDU 1242 这个题相比于普通的bfs有个特殊的地方,经过士兵时会额外消耗时间,也就是说此时最先搜到的时候不一定是用时最短的了.需要全部搜一遍才可以.这时候优先队列的好处就显现出来了.利用优先队列,可以让队列中的元素按时间排序,让先出来的总是时间短的,这样的话,最先搜到的一定是时间短的,就不用全部搜一遍了.PS:我是为了学优先队列做的这题..不是为了这题而现学的优先队列.. 代码如下: #include <iostream> #include <stdio.h> #i

POJ 2243 || HDU 1372:Knight Moves(BFS)

Knight Moves Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 11223 Accepted: 6331 Description A friend of you is doing research on the Traveling Knight Problem (TKP) where you are to find the shortest closed tour of knight moves that visit

hdu 4400 离散化+二分+BFS(暴搜剪枝还超时的时候可以借鉴一下)

Mines Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1110    Accepted Submission(s): 280 Problem Description Terrorists put some mines in a crowded square recently. The police evacuate all peo

HDU 4856 Tunnels(BFS+状压DP)

HDU 4856 Tunnels 题目链接 题意:给定一些管道,然后管道之间走是不用时间的,陆地上有障碍,陆地上走一步花费时间1,求遍历所有管道需要的最短时间,每个管道只能走一次 思路:先BFS预处理出两两管道的距离,然后状态压缩DP求解,dp[s][i]表示状态s,停在管道i时候的最小花费 代码: #include <cstdio> #include <cstring> #include <queue> #include <algorithm> using

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广搜 + 优先队列)

Rescue Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 14   Accepted Submission(s) : 7 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description Angel was caught by the MOLIGPY