考察: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 }