11624 - Fire!
题意:
有一个人在迷宫中,迷宫中还有点燃的活,每一秒钟人移动一个格子,火上下左右各移动一个格子,问人可不可以掏出迷宫。
这道题有两个解法,一个是先bfs火的移动,把每个格子的时间都记下来,在bfs人。
另一个是一起bfs,让火先出队列。
#include <bits/stdc++.h> using namespace std; int n, m, cnt; bool vis[1004][1004]; char maze[1004][1004]; int dx[4] = {0,1,0,-1}; int dy[4] = {1,0,-1,0}; int f[2][1004]; struct node{ int x, y, step; }a, b, temp; bool judge(node x) { if (x.x < 0 || x.y < 0 || x.x >= n || x.y >= m) return true; if (maze[x.x][x.y] == '#') return true; else if (vis[x.x][x.y]) return true; else return false; } int bfs(int x2, int y2) { queue<node> que[2]; memset(vis, false, sizeof(vis)); while (!que[0].empty()) que[0].pop(); while (!que[1].empty()) que[1].pop(); for (int i = 1; i <= cnt; i++) { temp.x = f[0][i], temp.y = f[1][i]; vis[temp.x][temp.y] = true; temp.step = 0; que[0].push(temp); } temp.x = x2, temp.y = y2; vis[temp.x][temp.y] = true; temp.step = 0; que[1].push(temp); int last = 0; while (que[1].size()) { //让当前步数的火先出队列 while (que[0].size() && last == que[0].front().step) { a = que[0].front(); que[0].pop(); for (int i = 0; i < 4; i++) { b.x = a.x + dx[i]; b.y = a.y + dy[i]; b.step = a.step + 1; if (judge(b)) continue; vis[b.x][b.y] = true; que[0].push(b); } } while (que[1].size() && last == que[1].front().step) { a = que[1].front(); que[1].pop(); if (a.x == 0 || a.y == 0 || a.x == n-1 || a.y == m-1) return a.step + 1; for (int i = 0; i < 4; i++) { b.x = a.x + dx[i]; b.y = a.y + dy[i]; b.step = a.step + 1; if (judge(b)) continue; vis[b.x][b.y] = true; que[1].push(b); } } //步数进行计数 last++; } return -1; } int main() { int t, fx, fy, jx, jy; scanf("%d", &t); while (t--) { cnt = 0; scanf("%d%d", &n, &m); for (int i = 0; i < n; i++) { scanf("%s", maze[i]); for (int j = 0; j < m; j++) { if (maze[i][j] == 'F') { f[0][++cnt] = i, f[1][cnt] = j; } else if (maze[i][j] == 'J') { jx = i, jy = j; } } } int ans = bfs(jx, jy); if (ans == -1) printf("IMPOSSIBLE "); else printf("%d ", ans); } return 0; }