UVA:11624 Fire!(双BFS+打表)

来源:互联网 发布:excel对比数据 编辑:程序博客网 时间:2024/06/17 12:12

题目地址: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;}


0 0