这个题很久以前就看到过,一直觉得好麻烦不想写,今天终于下定决心……花了两个多小时,总算是理解了。
题目大意:
给你一个NxM的方格,有一些格子已经着火了,一个人在s处,如果他能跑到t除就可以成功获救。人只能向东、西、南、北四个方向跑,而火经过时间t就会向东、西、南、北、东北、西北、东南、西南八个方向蔓延,使相邻的八个格子都着火,并且一旦着火,火就不会熄灭。问你最少经过多久这个人能获救,如果不能获救就输出Impossible。
题目思路:
这个题目需要一下预处理,先把每个格子着火的时间算出,这样就跟最基本的bfs一样了,入对的时候判断一下此时火是不是已经烧过来了就好了~
题目代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define maxn 105
using namespace std;
int dx[8]={1,1,0,-1,-1,-1,0,1};//火的八个方向
int dy[8]={0,-1,-1,-1,0,1,1,1};
int ddx[4]={1,0,-1,0};//人的四个方向
int ddy[4]={0,-1,0,1};
int vis[maxn][maxn];
int tim[maxn][maxn];
struct COO
{
int x,y;
int mit;
}start,mid,nxt;
int fx,fy,tx,ty;
int n,m,k;
queue<COO>q;
int bfs()//bfs模板
{
//memset(vis,0,sizeof(vis));
while(!q.empty())
{
q.pop();
}
//
start.x=fx;
start.y=fy;
vis[fx][fy]=1;
start.mit=0;
q.push(start);
while(!q.empty())
{
//printf("mm\n");
mid=q.front();
q.pop();
if(mid.x==tx&&mid.y==ty&&mid.mit<tim[tx][ty])
{
return mid.mit;
}
for(int i=0;i<4;i++)
{
int nx=mid.x+ddx[i];
int ny=mid.y+ddy[i];
if(nx>=0&&nx<n&&ny>=0&&ny<m&&!vis[nx][ny]&&(mid.mit+1)<tim[nx][ny])
{
//printf("ff\n");
nxt.mit=mid.mit+1;
nxt.x=nx;
nxt.y=ny;
vis[nx][ny]=1;
q.push(nxt);
}
}
}
return -1;
}
int main(void)
{
char ch[maxn][maxn];
while(~scanf("%d%d%d",&n,&m,&k)&&(n+m+k))
{
memset(tim,0x3f3f,sizeof(tim));
while(!q.empty())
{
q.pop();
}
//初始化
for(int i=0;i<n;i++)
{
scanf("%s",ch[i]);
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(ch[i][j]=='f')
{
tim[i][j]=0;
start.x=i;
start.y=j;
start.mit=0;
q.push(start);
}
if(ch[i][j]=='s')
{
fx=i;fy=j;
}
if(ch[i][j]=='t')
{
tx=i;ty=j;
}
}
}
//输入
while(!q.empty())
{
//printf("mm\n");
mid=q.front();
q.pop();
for(int i=0;i<8;i++)
{
int nx=mid.x+dx[i];
int ny=mid.y+dy[i];
nxt.x=nx;
nxt.y=ny;
if(nx>=0&&nx<n&&ny>=0&&ny<m)
{
nxt.x=nx;
nxt.y=ny;
nxt.mit=mid.mit+k;
//tim[nx][ny]=mid.mit+k;
if(nxt.mit<tim[nx][ny])//如果发现更早的时间就不断更新tim数组
{
tim[nx][ny]=nxt.mit;
q.push(nxt);//把该点再次入队,因为这时之前根据这个点扩散出去的都要重新算了
}
}
}
}
//预处理,留下的要用的是tim数组,所以可以用上面定义的队列和变量不用再定义有一个
memset(vis,0,sizeof(vis));
int ans=bfs();
//printf("%d-------------\n",ans);
if(ans==-1)
printf("Impossible\n");
else
printf("%d\n",ans);
}
return 0;
}
呼呼