UVA 11624 Fire! (技巧BFS)
阿新 • • 發佈:2019-02-18
題意:一個地圖中有空地有牆,空地可以走。地圖中有兩中物品,一種是人,每分鐘可以上下左右任走一格,一種是火,每分鐘會向上下左右一起擴散。問人是否可以逃脫迷宮。逃脫迷宮的條件是到達邊緣。
題解:我的思路比較奇特,我把火和人放在一個佇列中處理了。這種處理方式是先處理火,然後再處理人。為什麼這樣是對的呢如下圖:
就是佇列中一定是一段人,然後一段火,這樣保證人和火是同事進行的。單必須先把火比人先放進佇列中,這樣才能保證人不會走到火將要燒到的位置。如下圖
若人先走的火,人會向左走,但是火也會向右走,意味著火和人會走到一個格子裡。這是會燒死人的。
具體程式碼細節看註釋。
#include<cstdio> #include<iostream> #include<cstring> #include<iostream> #include<queue> using namespace std; const int maxn = 1010; char map[maxn][maxn]; // 地圖 int book[maxn][maxn]; // 標記陣列,記錄這點火或者人是否走過 struct node{ int x; //座標x int y; // 座標y int step; // 人的步數 int kind; // 用來區分是人還是火,1是人,0是火 }; queue<node> q; int n,m,ans; // n,m表示長寬。ans表示火的個數 node ren; //記錄人的起始位置 node fire[maxn]; // 記錄火的起始位置 int mov[4][2] = {1,0,-1,0,0,1,0,-1}; // 移動陣列 void bfs(){ node now,next; for(int i = 0 ; i < ans ; i++){ // 先把火入佇列 q.push(fire[i]); } q.push(ren); // 再把人放入佇列 // cout<<ren.step<<endl; while(!q.empty()){ now = q.front(); q.pop(); if(now.kind == 1 && (now.x == 0 || now.y== 0 || now.x == n-1 ||now.y == m-1)){ // 當是人到達邊緣時 cout << now.step+1 << endl; return ; } for(int i = 0 ; i < 4 ; i++){ // 對火對人進行移動 next.x = now.x+mov[i][0]; next.y = now.y+mov[i][1]; if(next.x < 0 || next.x >= n || next.y < 0 || next.y >= m || book[next.x][next.y] == 1 || map[next.x][next.y] == '#')//判斷是否可走和越界 continue; next.kind = now.kind; // 記錄種類 book[next.x][next.y] = 1; // 標記已走 // printf("%d %d %d\n",next.x,next.y,next.step); if(now.kind) // 若為人 順帶記錄步數 next.step = now.step + 1; q.push(next); //入佇列 } } cout << "IMPOSSIBLE" << endl; } int main(){ int z; cin >> z; while(z--){ while(!q.empty()) q.pop(); // 清空很重要 memset(map,0,sizeof(map)); memset(book,0,sizeof(book)); ans = 0; cin >> n >> m; for(int i = 0 ; i < n ; i++) cin >> map[i]; // 輸入地圖資訊 for(int i = 0 ; i < n ; i++){ for(int j = 0 ; j < m ; j++){ if(map[i][j] == 'J'){ // 查詢人的起始位置 ren.x = i; ren.y = j; ren.step = 0; ren.kind = 1; } if(map[i][j] == 'F'){ // 查詢所有火的起始位置 fire[ans].x = i; fire[ans].y = j; fire[ans].kind = 0; fire[ans].step = 0; ans ++; book[i][j]=1; } } } bfs(); } return 0; } /* 2 4 4 #### #JF# #..# #..# 3 3 ### #J. #.F */