【题意】一个迷宫里面有两个人,一个是M,一个是G,里面还有两个鬼,给出这个迷宫的状态。现在M每一秒可以走3步,G每一秒只能走一步。鬼每一秒可以走两步,鬼走过的地方人不能走,不然会死的很惨。现在问你M和G能不能相遇?如果能的话,输出需要走的时间。不能的话,输出-1.
【分析&解题思路】题目给的迷宫是800*800,所以考虑一般的bfs是过不了的,这里才用双向的bfs。但是题目里面还是包含一个坑点的,也许是我代码太丑,觉得这是坑点。具体细节就见我的AC代码啦QAQ!
【AC代码】
#include <cstdio>
#include <cstring>
#include <stdlib.h>
#include <queue>
#include <iostream>
using namespace std;
const int maxn = 802;
int dir[4][2]={{0,1},{0,-1},{-1,0},{1,0}};
struct node{
int x,y;
node(){}
node(int x,int y):x(x),y(y){}
};
int n,m;
char maze[maxn][maxn];
bool visit0[maxn][maxn];
bool visit1[maxn][maxn];
node ghost[2],st0,st1;
bool check(int x,int y){
if(x>=0&&x<n&&y>=0&&y<m) return true;
else return false;
}
bool validZ(int x,int y,int cost){
if(2*cost<abs(x-ghost[0].x)+abs(y-ghost[0].y)&&2*cost<abs(x-ghost[1].x)+abs(y-ghost[1].y)) return true;
else return false;
}
int two_bfs(){
int k,t=0,siz;
node now;
queue<node>Q0;
queue<node>Q1;
while(!Q0.empty()) Q0.pop();
while(!Q1.empty()) Q1.pop();
memset(visit0,false,sizeof(visit0));
memset(visit1,false,sizeof(visit1));
visit0[st0.x][st0.y]=true,visit1[st1.x][st1.y]=true;
Q0.push(st0);
Q1.push(st1);
while(!Q0.empty()||!Q1.empty()){
++t;
k=3;
while((k--)){
siz=Q0.size();
while(siz--){
now=Q0.front();
Q0.pop();
if(validZ(now.x,now.y,t)==false) continue;
for(int i=0;i<4;i++){
int dx=now.x+dir[i][0];
int dy=now.y+dir[i][1];
// if(visit1[dx][dy]==true) return t;这里必须要先判断一下是否能走到这个点,因此不能写在这里,wo坑了好久
if(check(dx,dy)&&validZ(dx,dy,t)&&!visit0[dx][dy]&&maze[dx][dy]!='X'){
if(visit1[dx][dy]==true) return t;
visit0[dx][dy]=true;
Q0.push(node(dx,dy));
}
}
}
}
siz=Q1.size();
while(siz--){
now=Q1.front();
Q1.pop();
if(validZ(now.x,now.y,t)==false) continue;
for(int i=0;i<4;i++){
int dx=now.x+dir[i][0];
int dy=now.y+dir[i][1];
// if(visit0[dx][dy]==true) return t;坑点之一
if(check(dx,dy)&&validZ(dx,dy,t)&&!visit1[dx][dy]&&maze[dx][dy]!='X'){
if(visit0[dx][dy]==true) return t;
visit1[dx][dy]=true;
Q1.push(node(dx,dy));
}
}
}
}
return -1;
}
int main(){
int tt,k;
scanf("%d",&tt);
while(tt--){
k=0;
scanf("%d%d",&n,&m);
for(int i=0; i<n; i++) scanf("%s",maze[i]);
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
if(maze[i][j]=='Z'){
ghost[k++]=node(i,j);
}else if(maze[i][j]=='M'){
st0=node(i,j);
}else if(maze[i][j]=='G'){
st1=node(i,j);
}
}
}
int ans=two_bfs();
printf("%d\n",ans);
}
return 0;
}