http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id
有一个人要从一个迷宫中逃出来,迷宫中‘#’表示不可走,‘.’表示可以走,但是迷宫失火了。火势以每秒向四周蔓延的速度蔓延。如果火已经蔓延到这里,人就不可走了,只要人走到迷宫的边缘就算成功逃出了。当然火无法蔓延到‘#’部分。问:至少需要几秒?注意火不是只有一个(我就是因为这个错了好多次);
思路:求一幅图,火势蔓延到该点的时间(BFS),然后直接BFS;就完成了。
#include <iostream>
#include <stdlib.h>
#include <cstdio>
#include <memory.h>
#include <queue>
#define maxn 1005
#define INF 10000005
using namespace std;
char map[maxn][maxn];
int MapTime[maxn][maxn];
int step[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int T,M,N;
struct my
{
int H,W,time;
}fire,men,now;
bool check(int H,int W)
{
bool flag=0;
fire.H=H;
fire.W=W;
fire.time=now.time+1;
if(0<=H&&H<N&&0<=W&&W<M)
{
if(map[H][W]!='#')flag=1;
}
return flag;
}
void FireBFS()
{
queue<my>Q;
for(int i=0;i<N;i++)
for(int j=0;j<M;j++)
{
MapTime[i][j]=INF;
if(map[i][j]=='F')
{
fire.H=i,fire.W=j,fire.time=1;
MapTime[fire.H][fire.W]=1;
Q.push(fire);
}
if(map[i][j]=='J')men.H=i,men.W=j,men.time=1;
}
while(!Q.empty())
{
now=Q.front();
Q.pop();
for(int i=0;i<4;i++)
{
if(check(now.H+step[i][0],now.W+step[i][1]))
{
if(MapTime[fire.H][fire.W]==INF)
{
MapTime[fire.H][fire.W]=fire.time;
Q.push(fire);
}
}
}
}
}
int BFS(my p)
{
queue<my>Q;
Q.push(p);
while(!Q.empty())
{
now=Q.front();
Q.pop();
if(now.H==N-1||now.W==M-1||now.H==0||now.W==0)
return now.time;
for(int i=0;i<4;i++)
{
if(check(now.H+step[i][0],now.W+step[i][1])&&MapTime[fire.H][fire.W]>fire.time)
{
if(fire.H==N-1||fire.W==M-1||fire.H==0||fire.W==0)
return fire.time;
map[fire.H][fire.W]='#';
Q.push(fire);
}
}
}
return -1;
}
int main()
{
// freopen("in.txt","r",stdin);
scanf("%d",&T);
while(T--)
{
memset(MapTime,0,sizeof MapTime);
memset(map,0,sizeof map);
scanf("%d%d",&N,&M);
for(int i=0;i<N;i++)
scanf("%s",map[i]);
FireBFS();
map[men.H][men.W]='#';
int a=BFS(men);
if(a!=-1)printf("%d\n",a);
else printf("IMPOSSIBLE\n");
}
return 0;
}