1. 程式人生 > 實用技巧 >Fire! UVA - 11624

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 }