kuangbin專題 專題一 簡單搜索 Fire! UVA - 11624

 

題目連接:https://vjudge.net/problem/UVA-11624

題意:一個迷宮,可能有一個或者多個地方着火了,每過1個時間消耗,火會向四周蔓延,問Joe能不能逃出迷宮,只要走出迷宮邊界就算逃出,火和Joe都不能透過牆。node

思路:人和火源分別跑bfs,人一張地圖,火源一張地圖,跑各自能到達點的時間,火源可能有多個,
最後只須要判斷迷宮的四個邊中人和火源的時間消耗來得出最小答案,出不去輸出「IMPOSSIBLE」,思路比較簡單,代碼稍微複雜點。ios


  1 #include <iostream>
  2 #include <cstring>
  3 #include<vector>
  4 #include<string>
  5 #include <cmath>
  6 #include <map>
  7 #include <queue>
  8 #include <algorithm>
  9 using namespace std;
 10 
 11 #define inf (1LL << 31) - 1
 12 #define rep(i,j,k) for(int i = (j); i <= (k); i++)
 13 #define rep__(i,j,k) for(int i = (j); i < (k); i++)
 14 #define per(i,j,k) for(int i = (j); i >= (k); i--)
 15 #define per__(i,j,k) for(int i = (j); i > (k); i--)
 16 
 17 const int N = 1010;
 18 int mv_x[] = { 0, 0, -1, 1 };
 19 int mv_y[] = { 1, -1, 0, 0 };
 20 char mp[N][N];
 21 int Fire[N][N]; //
 22 bool vis[N][N];
 23 int x[N];  //火源的x
 24 int y[N];  //火源的y
 25 int l;     //火源的個數
 26 int Joe[N][N];  //Joe
 27 int n, m;
 28 int pi, pj; //Joe的座標
 29 
 30 struct node{
 31     int x, y, v;
 32 };
 33 
 34 inline void init(){
 35     rep(i, 1, n) rep(j, 1, m){
 36         Joe[i][j] = 0;
 37         Fire[i][j] = inf;
 38     }
 39 }
 40 
 41 inline void input(){
 42 
 43     l = 0;
 44     rep(i, 1, n) rep(j, 1, m){
 45         cin >> mp[i][j];
 46         
 47         //記錄每一個火源
 48         if (mp[i][j] == 'J') pi = i, pj = j;
 49         else if (mp[i][j] == 'F') x[l] = i, y[l++] = j;
 50     }
 51 }
 52 
 53 inline bool check(int x, int y){
 54     return x >= 1 && x <= n && y >= 1 && y <= m;
 55 }
 56 
 57 void bfs_p(){
 58 
 59     queue<node> que;
 60     Joe[pi][pj] = 1;
 61     que.push(node{ pi, pj, 1 });
 62 
 63     while (!que.empty()){
 64 
 65         node tmp = que.front();
 66         que.pop();
 67         rep__(p, 0, 4){
 68 
 69             int dx = tmp.x + mv_x[p];
 70             int dy = tmp.y + mv_y[p];
 71 
 72             if (check(dx, dy) && !Joe[dx][dy] && mp[dx][dy] != '#'){
 73                 Joe[dx][dy] = tmp.v + 1;
 74                 que.push(node{ dx, dy, tmp.v + 1 });
 75             }
 76         }
 77     }
 78 }
 79 
 80 void bfs_f(int fi, int fj){
 81 
 82     rep(i, 1, n) rep(j, 1, m) vis[i][j] = 0;
 83     queue<node> que;
 84 
 85     Fire[fi][fj] = 1;
 86     vis[fi][fj] = true;
 87     que.push(node{ fi, fj, 1 });
 88 
 89     while (!que.empty()){
 90 
 91         node tmp = que.front();
 92         que.pop();
 93         rep__(p, 0, 4){
 94 
 95             int dx = tmp.x + mv_x[p];
 96             int dy = tmp.y + mv_y[p];
 97 
 98             if (check(dx, dy) && !vis[dx][dy] && mp[dx][dy] != '#'){
 99                 vis[dx][dy] = true;
100 
101                 if (tmp.v + 1 < Fire[dx][dy])  //比較與以前的火源,哪一個最早燒到這個點
102                     Fire[dx][dy] = tmp.v + 1, que.push(node{ dx, dy, tmp.v + 1 });
103 
104                 //    cout <<  "Fire[][] " <<  Fire[dx][dy] << endl;
105 
106             }
107         }
108     }
109 
110 
111 }
112 
113 void search_fire(){
114 
115     rep__(i, 0, l){
116         bfs_f(x[i], y[i]);
117     }
118 }
119 
120 void get_ans(){
121 
122     int ans = inf;
123 
124     //先把Fire地圖全部的inf,也就是沒法到達的點賦值爲0,方便比較
125     rep(i, 1, n) rep(j, 1, m) if (Fire[i][j] == inf) Fire[i][j] = 0;
126 
127     //一種狀況,Joe到達某點時間比Fire短,
128     //另外一個狀況,可能Fire到達不了那個點,因而Fire[x][y] == 0,全部有個特殊判斷 Fire[x][y] == 0
129     
130     //下面就是四個邊界狀況了
131     rep(i, 1, n){
132         if (i == 1 || i == n){
133             rep(j, 1, m){
134                 if (Joe[i][j] < Fire[i][j] || (Fire[i][j] == 0 && Joe[i][j] != 0)) 
135                     ans = min(ans, Joe[i][j]);
136             }
137         }
138         else {
139             if (Joe[i][1] < Fire[i][1] || (Fire[i][1] == 0 && Joe[i][1] != 0)) 
140                 ans = min(ans, Joe[i][1]);
141 
142             if (Joe[i][m] < Fire[i][m] || (Fire[i][m] == 0 && Joe[i][m] != 0)) 
143                 ans = min(ans, Joe[i][m]);
144         }
145     }
146 
147     if (ans == inf) cout << "IMPOSSIBLE" << endl;
148     else cout << ans << endl;
149 }
150 
151 int main(){
152 
153     ios::sync_with_stdio(false);
154     cin.tie(0);
155 
156     int T;
157     cin >> T;
158 
159     rep(i, 1, T){
160 
161         cin >> n >> m;
162         init(); //初始化
163         input();  //輸入
164         bfs_p();  //Joe的bfs
165         search_fire();  //全部火源的bfs
166         get_ans();  //獲得答案
167     }
168 
169 
170     return 0;
171 }
相關文章
相關標籤/搜索