题意:john要从迷宫里逃跑,迷宫里有着火的地方,并且火势可以蔓延,问john是否可以逃出来,如果可以输出最短时间。
思路:我觉得这道题很好,以前没做过,需要从两个方向进行搜索,首先对火进行处理,保存下火到达每个格子的时间,然后再对john进行bfs,在对john进行bfs是,只需要加一个条件,判断john到达每个格子的时间与原来火到达此地的时间,哪个大。
代码如下:
#include<iostream>
#include<cstring>
#include<queue>
#include<cstdio>
#include<algorithm>
#include<climits>
using namespace std;
const int maxn=1010;
const int inf=100000000;
struct A
{
int x,y,tim;
};
char maze[maxn][maxn];
int Time[maxn][maxn];
int vis[maxn][maxn];
int sx,sy;
int r,c;
int dx[]= {1,-1,0,0};
int dy[]= {0,0,1,-1};
queue<A> fire;
int ans;
void bfs(int num)
{
A a;
while(!fire.empty())
{
a=fire.front();
fire.pop();
if(num)
if((a.x>=r)||(a.x<=1)||(a.y>=c)||(a.y<=1))
{
ans=min(a.tim,ans);
}
A b;
for(int i=0; i<4; i++)
{
b.x=a.x+dx[i];
b.y=a.y+dy[i];
if(b.x>=1&&b.x<=r&&b.y>=1&&b.y<=c&&(maze[b.x][b.y]!='#')&&(!vis[b.x][b.y])&&(Time[b.x][b.y]>a.tim+1))
{
b.tim=a.tim+1;
Time[b.x][b.y]=b.tim;
vis[b.x][b.y]=1;
fire.push(b);
}
}
}
}
int main()
{
//freopen("in.txt","r",stdin);
int t;
cin>>t;
while(t--)
{
cin>>r>>c;
A p;
//memset(maze ,'\0',sizeof(maze));
for(int i=1;i<=fire.size();i++)
fire.pop();
ans=0;
for(int i=1; i<=r; i++)
for(int j=1; j<=c; j++)
{
cin>>maze[i][j];
if(maze[i][j]=='J')
sx=i,sy=j;
if(maze[i][j]=='F')
{
p.x=i,p.y=j,p.tim=1;
vis[p.x][p.y]=1;
fire.push(p);
}
Time[i][j]=inf;
}
memset(vis,0,sizeof(vis));
bfs(0);
ans=inf;
memset(vis,0,sizeof(vis));
p.x=sx,p.y=sy,p.tim=1;
vis[p.x][p.y]=1;
fire.push(p);
bfs(1);
if(ans!=inf)
cout<<ans<<endl;
else
cout<<"IMPOSSIBLE"<<endl;
}
return 0;
}