问题描述:在一个R x C的迷宫中,'.'代表通路,'#'代表墙,'F'代表起火点,'J'代表Joe的位置,在每个单位时间内,火和人都可以向上下左右四个方向移动一格,注意,人和火均不能到达墙的位置,如果人能够到达迷宫的边界,就可以逃出迷宫,问需要的最短时间,如果不能逃生输出-1
题解思路:BFS,题解的关键是先让火灾点入队列,再让人入队列,火灾先到达的点,人不能到达,火灾能够蔓延到人的位置,
如果人能到达边界则返回需要的时间,否则返回-1。程序为节省空间,可以使火灾到达的点置为'#',具体看代码
AC的C++程序:
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int N=1005;
//方向
struct DIR{
int x,y;
}d[4]={{-1,0},{1,0},{0,-1},{0,1}};
struct Node{
int x,y,t;
char c;//c='F'表示火 c='J'表示人
Node(int x,int y,int t,char c):x(x),y(y),t(t),c(c){}
};
int R,C;
queue<Node>q;
char g[N][N];
int bfs()
{
while(!q.empty()){
Node f=q.front();
q.pop();
if(f.c=='J'&&(f.x==1||f.x==R||f.y==1||f.y==C))//逃出火场,返回步数
return f.t;
for(int i=0;i<4;i++){
int fx=f.x+d[i].x;
int fy=f.y+d[i].y;
if(1<=fx&&fx<=R&&1<=fy&&fy<=C&&g[fx][fy]=='.'||(f.c=='F'&&g[fx][fy]=='J')){
if(g[fx][fy]=='.')
g[fx][fy]='#';
q.push(Node(fx,fy,f.t+1,f.c));
}
}
}
return -1;//返回-1表示不能逃出火场
}
int main()
{
int t,x,y;
scanf("%d",&t);
while(t--){
//清空队列
while(!q.empty())
q.pop();
scanf("%d%d",&R,&C);
//先压入'F'再压入'J'
for(int i=1;i<=R;i++)
for(int j=1;j<=C;j++){
scanf(" %c",&g[i][j]);
if(g[i][j]=='J'){
x=i;
y=j;
}
else if(g[i][j]=='F'){
g[i][j]='#';
q.push(Node(i,j,1,'F'));
}
}
q.push(Node(x,y,1,'J'));//压入J
int ans=bfs();
if(ans==-1)
printf("IMPOSSIBLE\n");
else
printf("%d\n",ans);
}
return 0;
}