一、内容
题目描述
乔在迷宫中工作。不幸的是,迷宫的一部分着火了,迷宫的主人没有制定火灾的逃跑计划。请帮助乔逃离迷宫。根据乔在迷宫中的位置以及迷宫的哪个方块着火,你必须确定火焰烧到他之前,乔是否可以离开迷宫,如果能离开他能跑多快。
乔和火每分钟移动一个方格,上、下、左、右,四个方向中的一个。火势向四个方向同时蔓延。乔可以从迷宫的任何一个边界逃离迷宫。无论是乔还是火都不会到达有墙的位置。
输入
第一行输入包含一个整数,即测试次数
每个测试用例的第一行包含两个
整数R和C,用空格分隔,1≤R,C≤1000
下面R行中,每一行都包含C个字符,以及每个字符是以下之一:
# 代表墙
. 代表空地,火和乔是可通行的
J 乔在迷宫中最初的位置,火和乔是可通行的
F 代表火
在每组测试中只有一个J
输出
对于每个测试用例,如果在火蔓延的时候烧到了乔,则乔无法逃出迷宫,输出'IMPOSSIBLE'如果乔能逃出迷宫,则输出乔最快可以在几分钟内安全逃出迷宫,每组输出占一行
样例输入
2
4 4
####
#JF#
#..#
#..#
3 3
###
#J.
#.F
样例输出
3
IMPOSSIBLE
二、思路
- 用2个队列分别更新J的状态和火的状态,每秒钟将各自队列里面的节点全部更新完。
- 先更新J的位置,再更新火的状态,同一秒中J先走,火再蔓延。
三、代码
#include <cstdio>
#include <iostream>
#include <queue>
#include <cstring>
using namespace std;
const int N = 1005;
int t, n, m, vis[N][N];
char g[N][N];
int dx[4] = {1, 0, 0, -1};
int dy[4] = {0, 1, -1, 0};
struct node {
int x, y;
node(int x, int y): x(x), y(y){}
};
void bfs() {
queue<node> jq; //J所在的点的队列
queue<node> fq; //着火点的队列
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (g[i][j] == 'J') {
jq.push(node(i, j));
vis[i][j] = 1;
} else if (g[i][j] == 'F') {
fq.push(node(i, j));
g[i][j] = '#';//代表不可走
}
}
}
int step = 0;
int cnt= 0;
while (jq.size()) {
step++; //每秒中更新队列里面的所有点
//J先跑 火再蔓延
for (int i = 0, j = jq.size(); i < j; i++) {
node t = jq.front();
jq.pop();
//表明这个点被火给蔓延了不能走了 因为是人先走,火再蔓延
if (g[t.x][t.y] == '#') continue;
for (int k = 0; k < 4; k++) {
int fx = t.x + dx[k];
int fy = t.y + dy[k];
if (fx >= 0 && fy >= 0 && fx < n &&fy < m) {
//表明下个点可走入队
if (g[fx][fy] != '#' && !vis[fx][fy]) {
jq.push(node(fx, fy));
vis[fx][fy] = 1;
}
} else {
//代表走出了边界
printf("%d\n", step);
return;
}
}
}
//火蔓延
for (int i = 0, j = fq.size(); i < j; i++) {
node t = fq.front();
fq.pop();
for (int k = 0; k < 4; k++) {
int fx = t.x + dx[k];
int fy = t.y + dy[k];
if (fx >= 0 && fy >= 0 && fx < n && fy < m && g[fx][fy] != '#') {
fq.push(node(fx, fy));
g[fx][fy] = '#';
}
}
}
}
printf("IMPOSSIBLE\n");
}
int main() {
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++) {
scanf("%s", g[i]);
}
bfs();
memset(vis, 0, sizeof vis);
}
return 0;
}