原题链接

考察:bfs

第一思路:

        预处理鬼到达每个点的最短时间,再对男孩与女孩分别bfs...体感没错,不知道会不会MLE,但本蒟蒻连样例都没过....

省事思路:

        压根不用对鬼bfs.如果鬼能在k秒后达到某点,说明鬼的起点与终点的曼哈顿距离<=2*k.本蒟蒻完全没想到....

        接下来是对男女分别bfs直到他们碰面.这里就有点像双向bfs.但这道题很怪,或者说题意不明.这里鬼是先动的,也就是如果新时间人还没动,就要判断鬼是否能走到这里,不能才能扩展.还有一个比较迷的是新时间点某个人还没动,另一个人已经到达就可以判对.但是本蒟蒻觉得按上面鬼先动的原则,如果被找到的人还未动前先被鬼找到,这人在见面前不就gg

        好迷.....

        还有就是这里不能先扩展队列少的人,然后队列为空就return -1.因为这里男的是走三步的,他可能是走第三步的时候队列才为空,还需要看女的是否能与他会合.

 1 #include <iostream> 
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <queue>
 5 using namespace std;
 6 typedef pair<int,int> PII;
 7 const int N = 810,M = 6,INF = 0x3f3f3f3f;
 8 char mp[N][N];
 9 int n,m,vis[N][N],xx[4] ={-1,1,0,0},yy[4] ={0,0,-1,1};
10 int dist[2][N][N];
11 PII p[M];
12 int foot[3] = {1,3};
13 struct Node{
14     int x,y,ti;
15     bool isman;
16 };
17 bool check(int x,int y,int ti)
18 {
19     if(ti*2>=abs(p[1].first-x)+abs(p[1].second-y)) return false;
20     if(ti*2>=abs(p[2].first-x)+abs(p[2].second-y)) return false;
21     return 1;
22 }
23 int extend(queue<Node>& q,int idx)
24 {
25     int T = foot[idx];
26     int ts = q.front().ti;
27     while(T--)
28     {
29         int sz = q.size();
30         while(sz--)
31         {
32             Node it = q.front();
33             q.pop();
34             int x = it.x,y = it.y;
35             if(!check(x,y,ts+1)) continue;
36             for(int i=0;i<4;i++)
37             {
38                 int dx = x+xx[i],dy = y+yy[i];
39                 if(dx>0&&dx<=n&&dy>0&&dy<=m&&check(dx,dy,ts+1)&&mp[dx][dy]!='X')
40                 {
41                     if(dist[idx][dx][dy]!=INF) continue;
42                     if(dist[idx^1][dx][dy]<=ts+1) return ts+1;
43                     dist[idx][dx][dy] = ts+1;
44                     Node news; news.isman = it.isman;
45                     news.ti = ts+1; news.x = dx,news.y = dy;
46                     q.push(news);
47                 }
48             }
49         }
50     }
51     return -1;
52 }
53 int go_bfs(Node m,Node w)
54 {
55     queue<Node> q[2];
56     memset(dist,0x3f,sizeof dist);
57     q[1].push(m),q[0].push(w);
58     dist[m.isman][m.x][m.y] = 0;
59     dist[w.isman][w.x][w.y] = 0;
60     while(q[1].size()&&q[0].size())
61     {
62         int s = extend(q[1],1);
63         if(s!=-1) return s;
64         s = extend(q[0],0);
65         if(s!=-1) return s;
66     }
67     return -1;
68 }
69 int main()
70 {
71     int T;
72     scanf("%d",&T);
73     while(T--)
74     {
75         scanf("%d%d",&n,&m);
76         for(int i=1;i<=n;i++) scanf("%s",mp[i]+1);
77         int gz = 0;
78         Node man,woman;
79         for(int i=1;i<=n;i++)
80           for(int j=1;j<=m;j++)
81             if(mp[i][j]=='M') man.x = i,man.y = j,man.isman = 1;
82             else if(mp[i][j]=='G') woman.x = i,woman.y = j,woman.isman = 0;
83             else if(mp[i][j]=='Z') p[++gz].first = i,p[gz].second = j;
84         woman.ti = man.ti = 0;
85         printf("%d\n",go_bfs(man,woman));
86     }
87     return 0;
88 }