Fire Game
阿新 • • 發佈:2020-07-30
Fire Game
這題讓我明白了兩件事:
- 做啥題之前都要先看資料範圍。上一道題這麼暴力的bfs是T了的,不過這題地圖就10*10,暴力就行了,
- 思路越簡單,寫的越不容易出錯。一開始思路偏了,後面再怎麼小心都很難救回來。
最開始寫的150行,感覺考慮了各個方面,寫了很久,WA。
看了題解,思路一樣。於是按題解的結構重新寫了一遍,寫的很快,不到100行,AC。
題目大意:防火燒草叢,能同時從兩個地方燒。問最短燒完時間是多少。
暴力列舉每兩個草叢,直到最少值。還要檢測一下草坪燒乾淨沒有。
(最開始我想的先判斷連通塊數量,再根據連通塊數量搞bfs...)
//#include <bits/stdc++.h> #include <queue> #include <iostream> #include <cstring> using namespace std; typedef long long ll; typedef unsigned long long ull; int mod = 9973; const int INF = 0x3f3f3f3f; const int maxn = 1e3 + 10; struct node { int x, y, cnt; node(int x, int y, int cnt) : x(x), y(y), cnt(cnt){}; node() : x(), y(), cnt(){}; }; int n, m; char Map[12][12]; int vis[12][12]; vector<node> v; void init() { memset(vis, 0, sizeof(vis)); memset(Map, 0, sizeof(Map)); v.clear(); } int legal(node a) { if (a.x >= 0 && a.x < m && a.y >= 0 && a.y < n && Map[a.y][a.x] == '#') return 1; return 0; } int dx[] = {0, 0, 1, -1}; int dy[] = {1, -1, 0, 0}; int bfs(node a, node b) { memset(vis, 0, sizeof(vis)); vis[a.y][a.x] = vis[b.y][b.x] = 1; queue<node> q; node t, r; int res = INF; q.push(a), q.push(b); while (!q.empty()) { t = q.front(); res = t.cnt; r.cnt = t.cnt + 1; q.pop(); for (int i = 0; i < 4; i++) { r.x = t.x + dx[i]; r.y = t.y + dy[i]; if (!vis[r.y][r.x] && legal(r)) { q.push(r); vis[r.y][r.x] = 1; } } } for (int i = 0; i < v.size(); i++) if (Map[v[i].y][v[i].x] == '#' && vis[v[i].y][v[i].x] == 0) return INF; return res; } int main() { int T; cin >> T; for (int z = 1; z <= T; z++) { cin >> n >> m; init(); 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] == '#') v.push_back(node(j, i, 0)); if (v.size() <= 1) cout << "Case " << z << ": " << 0 << endl; else { int ans = INF; for (int i = 0; i < v.size(); i++) for (int j = i + 1; j < v.size(); j++) ans = min(ans, bfs(v[i], v[j])); if (ans == INF) cout << "Case " << z << ": " << -1 << endl; else cout << "Case " << z << ": " << ans << endl; } } return 0; }