题目地址:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2671(这个题目是pdf格式的,不能直接复制下来)
题目大意:一个人在迷宫里,里面失火了,那个火苗每秒会向四周蔓延,当这个人到达迷宫边界的时候就能逃脱迷宫了,问这个人能否逃出迷宫,逃出用时多久。
解题思路:朴素的方法会超时,这里先把火苗蔓延到每个点的用时打表,在把人到每个地方的用时打表(给人打表时,看是否能走,前面是否有火,才能入队)
代码如下:
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
char map[1010][1010];
int people[1010][1010];//储存人到某点的时间
int fire[1010][1010];//储存火到某点的时间
int t,n,m;
int jn,jm,fn,fm;
int dn[4]={-1,1,0,0};
int dm[4]={0,0,-1,1};
struct node
{
int n,m;
};
queue<node>qfire;
queue<node>qpeople;
bool judgefire(int hang,int lie)//火能烧到.和 J所在的位置
{
if(hang>=0&&lie>=0&&hang<n&&lie<m&&(map[hang][lie]=='.'||map[hang][lie]=='J')&&fire[hang][lie]==-1)
{
return true;
}
else
{
return false;
}
}
bool judgepeople(int hang,int lie)//判断人能不能走
{
if(hang>=0&&lie>=0&&hang<n&&lie<m&&map[hang][lie]=='.'&&people[hang][lie]==-1)
{
return true;
}
else
{
return false;
}
}
void bfsfire()//给火苗打表
{
while(!qfire.empty())
{
struct node tmp;
tmp=qfire.front();
qfire.pop();
for(int i=0;i<4;i++)
{
if(judgefire(tmp.n+dn[i],tmp.m+dm[i]))
{
struct node tmp2;
tmp2.n=tmp.n+dn[i];
tmp2.m=tmp.m+dm[i];
fire[tmp2.n][tmp2.m]=fire[tmp.n][tmp.m]+1;
qfire.push(tmp2);
}
}
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
printf("%d ",fire[i][j]);
}
printf("\n");
}
}
void bfspeople()//给人打表
{
int flag=0;
while(!qpeople.empty())
{
struct node tmp=qpeople.front();
qpeople.pop();
if(tmp.n==0||tmp.m==0||tmp.n==n-1||tmp.m==m-1)//走到边界了,再跨一步就逃脱了,所以下面+1
{
printf("%d\n",people[tmp.n][tmp.m]+1);
flag=1;
break;
}
for(int i=0;i<4;i++)
{
if(judgepeople(tmp.n+dn[i],tmp.m+dm[i]))
{
if(fire[tmp.n+dn[i]][tmp.m+dm[i]]==-1)//这里是避免那种情况,之前给火苗打表,但是有的点被墙壁包围,火蔓延不到,人有可能走到的地方
{
struct node k1;
people[tmp.n+dn[i]][tmp.m+dm[i]]=people[tmp.n][tmp.m]+1;
k1.n=tmp.n+dn[i];
k1.m=tmp.m+dm[i];
qpeople.push(k1);
}
else
{
struct node tmp2;
tmp2.n=tmp.n+dn[i];
tmp2.m=tmp.m+dm[i];
people[tmp2.n][tmp2.m]=people[tmp.n][tmp.m]+1;
if(people[tmp2.n][tmp2.m]<fire[tmp2.n][tmp2.m])//人比火先到达那个地方
{
qpeople.push(tmp2);
}
}
}
}
}
if(flag==0)
{
printf("IMPOSSIBLE\n");
}
}
int main()
{
scanf("%d",&t);
while(t--)
{
while(!qfire.empty())
{
qfire.pop();
}
while(!qpeople.empty())
{
qpeople.pop();
}
memset(fire,-1,sizeof(fire));//-1也算是个标记了,标记是否访问过了
memset(people,-1,sizeof(people));
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%s",&map[i]);
for(int j=0;j<m;j++)
{
if(map[i][j]=='J')
{
struct node tmp;
tmp.n=i;
tmp.m=j;
people[i][j]=0;
qpeople.push(tmp);
}
if(map[i][j]=='F')
{
struct node tmp;
tmp.n=i;
tmp.m=j;
fire[i][j]=0;
qfire.push(tmp);
}
}
}
bfsfire();
bfspeople();
}
return 0;
}