题意:在迷宫里有两个人,一个三步,一个一步,还有两个鬼 每秒占距离为2的格子而且不停扩散。
题解:双BFS。可以用参数传递的方式写一个BFS,但是如果只是双BFS直接写两个函数比较好。
对于步数可以大于一步的情况,可以在外层用step,一层一层来。
不要忘了传递队列。
#include<cstdio> #include<iostream> #include<cstring> #include<queue> using namespace std; char mp[805][805]; int n,m,cnt,step; int gx,gy,mx,my; struct node { int x,y; }a,g[2]; queue <node > que1,que2,que; int dir[4][2]={1,0,-1,0,0,1,0,-1}; int myabs(int x){ if (x>0)return x; return -x; } int dis(node a){ int temp; temp=myabs(a.x-g[0].x)+myabs(a.y-g[0].y); temp=min(temp,myabs(a.x-g[1].x)+myabs(a.y-g[1].y)); return temp; } int check(node p){ if(p.x>=n||p.y>=m||p.x<0||p.y<0)return 1; if(dis(p)<=2*step)return 1;//检查距离 if(mp[p.x][p.y]=='X')return 1; return 0; } int m_bfs(){//m的广搜 node next; int i,j; que=que1; for(i=0;i<3;i++){ while(!que.empty()){ a=que.front(); que.pop(); que1.pop(); if(check(a))continue; for(j=0;j<4;j++){ next.x=a.x+dir[j][0]; next.y=a.y+dir[j][1]; if(check(next))continue; if(mp[next.x][next.y]=='M')continue; if(mp[next.x][next.y]=='G')return 1; mp[next.x][next.y]='M'; que1.push(next); } } que=que1;//传递 } return 0; } int g_bfs(){//g的广搜 int i,j; node next; que=que2; while(!que.empty()){ a=que.front(); que.pop(); que2.pop(); if(check(a))continue; for(i=0;i<4;i++){ next.x=a.x+dir[i][0]; next.y=a.y+dir[i][1]; if(check(next))continue; if(mp[next.x][next.y]=='G')continue; if(mp[next.x][next.y]=='M')return 1; mp[next.x][next.y]='G'; que2.push(next); } } return 0; } void in_it(){ while(!que.empty())que.pop(); while(!que1.empty())que1.pop(); while(!que2.empty())que2.pop(); int i,j,cnt=0;//初始化 for(i=0;i<n;i++)scanf("%s",mp[i]);//用cin和%c 都会超时 for(i=0;i<n;i++){ for(j=0;j<m;j++){ if(mp[i][j]=='M')mx=i,my=j; if(mp[i][j]=='G')gx=i,gy=j; if(mp[i][j]=='Z') g[cnt].x=i,g[cnt++].y=j; } } } int main(){ int i,j; int f1,f2; int t; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&m); in_it(); step=0; a.x=mx,a.y=my; que1.push(a); a.x=gx,a.y=gy; que2.push(a); int flag=-1; while(!que1.empty()&&!que2.empty()){ step++;//一步一步来 f1=m_bfs(); f2=g_bfs(); if(f1||f2){ flag=step; break; } } /* for(i=1;i<=n;i++){ for(j=1;j<=m;j++)printf("%c",mp[i][j]); printf("\n"); }*/ printf("%d\n",flag); } }