Fire! UVA - 11624
题目:https://vjudge.net/problem/UVA-11624/origin
我最先想的是先bfs火焰蔓延,用一个三维数组记录不同步数下的火焰情况。(第一位是步数,第二维第三维是坐标)然后再bfsJoe的走路情况。但是在bfs火焰蔓延的地方有些麻烦。
百度了一下有两种想法:
第一种:先bfs火源的蔓延情况, 用一个time[mx][mx]二维数组记录每个点被火焰侵袭的最早的步数。然后进行Joe的bfs,在他走的每一步中都对当前步数和走的地点的被火侵袭的步数进行比较,来判断是否会被烧到
第二种:同时bfs火焰和Joe,但是要先把火焰放到队列里,然后再把Joe放到队列里。这样的好处是以火焰和Joe一个来回中,步数是相同的,只要判断某个地点是否被在前面的的运算过程中是否经过就可以使Joe走不到火焰里。
代码(第二种思路):
1 #include<iostream> 2 #include<cstring> 3 #include<fstream> 4 #include<algorithm> 5 #include<queue> 6 using namespace std; 7 typedef long long ll; 8 const ll mx=1e3+10; 9 ll to[5][2]={{0,1},{0,-1},{1,0},{-1,0},{0,0}};//方向 10 typedef struct node{ 11 ll i, j, step, fire; 12 node(){} 13 node(ll i, ll j, ll step, ll fire):i(i), j(j), step(step), fire(fire){} 14 }NODE; 15 ll T, h, l, vis[mx][mx]; 16 char in[mx][mx]; 17 queue<NODE>q; 18 NODE J; 19 bool isright(ll i, ll j){//判断是否走出去了; 20 return i>=1&&i<=h&&j>=1&&j<=l; 21 } 22 ll bfs(){ 23 while(!q.empty()){ 24 NODE curr=q.front(); 25 q.pop(); 26 27 for(ll i=0;i<=3;i++){ 28 ll ni=curr.i+to[i][0], nj=curr.j+to[i][1]; 29 if(isright(ni, nj)){//判断是否越界 30 if(vis[ni][nj]==1) continue;//经过 31 if(in[ni][nj]=='#')continue;//墙 32 vis[ni][nj]=1; 33 q.push(NODE(ni, nj, curr.step+1, curr.fire)); 34 }else if(curr.fire==0)//越界 如果是Joe说明escape成功 35 return curr.step+1; 36 37 } 38 } 39 return -1; 40 } 41 int main(){ 42 cin>>T; 43 for(ll lp=1;lp<=T;lp++){ 44 while(!q.empty()) q.pop(); 45 memset(vis, 0, sizeof(vis)); 46 47 cin>>h>>l; 48 cin.ignore(); 49 for(ll i=1;i<=h;i++){ 50 for(ll j=1;j<=l;j++){ 51 in[i][j]=getchar(); 52 if(in[i][j]=='J') J=NODE(i, j, 0, 0);//Joe 53 if(in[i][j]=='F') q.push(NODE(i, j, 0, 1)), vis[i][j]=1; 54 //将火焰放到队列里 55 56 } 57 getchar(); 58 } 59 q.push(J);//放完火焰放Joe 60 61 ll res=bfs(); 62 if(res==-1){ 63 cout<<"IMPOSSIBLE"<<endl; 64 }else{ 65 cout<<res<<endl; 66 } 67 } 68 return 0; 69 }