小A和小B和幽灵追两人(双向BFS)
链接:https://ac.nowcoder.com/acm/contest/549/G
来源:牛客网
小A与小B这次两个人都被困在了迷宫里面的两个不同的位置,而他们希望能够迅速找到对方,然后再考虑如何逃离迷宫的事情。小A每次可以移动一个位置,而小B每次可以移动两次位置,小A移动的方向是上下左右左上左下右上右下8个方向,小B移动的方向是上下左右4个方向,请问他们最早什么时候能够找到对方,如果他们最终无法相遇,那么就输出”NO"。
输入描述:
第一行两个整数N,M分别表示迷宫的行和列。接下来一个N×M的矩阵其中"C"表示小A的位置,"D"表示小B的的位置,"#"表示不可通过的障碍,"."则是可以正常通过的位置。字符用空格隔开第一行两个整数N,M分别表示迷宫的行和列。
接下来一个N*M 的矩阵
输出描述:
如果可以相遇,第一行输出一个YES,第二行一个整数输出最短的相遇时间。
否则就输出一个NO表示不能相遇。
备注:
1≤n,m≤1000
两个人走过的路径分别用
vis[0][maxn][maxn]
vis[1][maxn][maxn]
来标记。
小a走的时候
1.检查自己的地图(防止重复走一个地方)
2.检查小b的地图,看看小b是否走过这个地方(如果小b走过了,那就可以视为他们相遇了)
同理可得:
小b走的时候
1.检查自己的地图(防止重复走一个地方)
2.检查小a的地图,看看小a是否走过这个地方(如果小a走过了,那就可以视为他们相遇了)
基本思想就是:
我们标记小A和小B走过的地方,如果小B走到小A走过的/小A走到小B走过的地方,那么就直接输出当前时间
#include<iostream> #include<algorithm> #include<queue> using namespace std; /* 这个题就是说,两个人能不能相遇, 第一个人一次移动一个位置,方向是上下左右左上左下右上右下8个方向 第二个人一次移动两个位置,方向是上下左右 */ const int maxn=1010; int dx[8]={0,0,1,-1,1,1,-1,-1}; int dy[8]={1,-1,0,0,1,-1,1,-1}; bool vis[2][maxn][maxn]; char map[maxn][maxn]; int n,m; struct node{ int x,y; }; queue<node> q[2]; bool bfs(int x){ int sz=q[x].size(); while(sz--){//这里要注意 node temp=q[x].front(); q[x].pop(); for(int i=0;i<8-4*x;i++){ int nx=temp.x+dx[i],ny=temp.y+dy[i]; if(nx<0||nx>=n||ny<0||ny>=m||map[nx][ny]=='#') continue; if(vis[1-x][nx][ny]) return true; if(!vis[x][nx][ny]){ q[x].push(node{nx,ny}); vis[x][nx][ny]=true; } } } return false; } int min_step(){ int res=0; while(!q[0].empty()||!q[1].empty()){ res++; if(bfs(0)) return res; if(bfs(1)) return res; if(bfs(1)) return res; } return -1; } int main(){ cin>>n>>m; for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ cin>>map[i][j]; if(map[i][j]=='C'){ q[0].push(node{i,j}); vis[0][i][j]=true; } else if(map[i][j]=='D'){ q[1].push(node{i,j}); vis[1][i][j]=true; } } } int ans=min_step(); if(ans==-1){ cout<<"NO"<<endl; } else{ cout<<"YES"<<endl; cout<<ans<<endl; } }
然后这个HDU3085和上面的差不多:
题目大意:给出一个迷宫,一个男孩和一个女孩还有两只鬼,男孩每秒钟走3格,女孩每秒钟走1格,鬼每秒钟向四周分裂2格,问男孩和女孩能否在鬼占领迷宫之前汇合,能的话输出汇合最短时间,否则输出-1
这个和那个思路是一样的就是多了一个判断是否被鬼魂追到
#include<iostream> #include<algorithm> #include<queue> #include<cstring> using namespace std; const int maxn=1e3+100; char map[maxn][maxn]; bool vis[2][maxn][maxn]; int dx[]={0,0,1,-1}; int dy[]={1,-1,0,0}; struct node{ int x,y; }g[2]; int k,step; int n,m; queue<node>q[2]; bool check(int x,int y) { if(x<0||y<0||x>=n||y>=m) return false; if(map[x][y]=='X') return false; for(int i=0;i<2;i++) if(step*2>=abs(x-g[i].x)+abs(y-g[i].y)) return false; return true; } int bfs(int x){ int sz=q[x].size(); while(sz--){ node temp=q[x].front(); q[x].pop(); if(!check(temp.x,temp.y)){ continue; } for(int i=0;i<4;i++){ int nx=temp.x+dx[i]; int ny=temp.y+dy[i]; if(!check(nx,ny)) continue; if(vis[1-x][nx][ny]){ return true; } if(!vis[x][nx][ny]){ q[x].push(node{nx,ny}); vis[x][nx][ny]=true; } } } return false; } int min_step(){ step=0; while(!q[0].empty()||!q[1].empty()){ step++; if(bfs(0)) return step; if(bfs(0)) return step; if(bfs(0)) return step; if(bfs(1)) return step; } return -1; } int main(){ int t; cin>>t; while(t--){ memset(vis,false,sizeof(vis)); while(!q[0].empty()) q[0].pop(); while(!q[1].empty()) q[1].pop(); cin>>n>>m; k=0; for(int i=0;i<n;i++){ scanf("%s",map[i]); } for(int i=0;i<n;i++){ for(int j=0;j<m;j++){ if(map[i][j]=='M'){ q[0].push(node{i,j}); vis[0][i][j]=true; } else if(map[i][j]=='G'){ q[1].push(node{i,j}); vis[1][i][j]=true; } else if(map[i][j]=='Z'){ g[k].x=i; g[k].y=j; k++; } } } int ans=min_step(); cout<<ans<<endl; } }
令一种写法:传送门