题目大意:迷宫着火,请帮助乔逃离迷宫。根据乔在迷宫中的位置以及迷宫的哪个方块着火,你必须确定火焰烧到他之前,乔是否可以离开迷宫。
乔和火每分钟移动一个方格,上、下、左、右,四个方向中的一个。火势向四个方向同时蔓延。乔可以从迷宫的任何一个边界逃离迷宫。无论是乔还是火都不会到达有墙的位置。
第一行包含两个整数R和C(迷宫长宽),1≤R,C≤1000。
双重 bfs 可以解决,注意乔可能呆在一个火烧不到的地方,此时 fire [ ][ ] 有不同的情况,需要分开判断。
已经修改,因为火的数量不止一个,所以之前错了,多谢热心博友的解答,现已修改。
赋个别人的代码
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int inf = 0x3f3f3f3f;
int r, c;
char map[1010][1010];
int fire[1010][1010];
int vis[1010][1010];
int dis[4][2] = {{1, 0},
{-1, 0},
{0, 1},
{0, -1}};
struct node {
int x, y;
} start, nnext, jj, ff;
void ff_bfs(node ff) {
memset(fire, -1, sizeof(fire));
queue<node> q;
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
if (map[i][j] == 'F') {
ff.x = i, ff.y = j;
fire[ff.x][ff.y] = 0;
q.push(ff);
}
}
}
while (!q.empty()) {
start = q.front();
q.pop();
for (int i = 0; i < 4; i++) {
nnext.x = start.x + dis[i][0];
nnext.y = start.y + dis[i][1];
/**
if(nnext.x>=0&&nnext.y>=0&&nnext.x<r&&nnext.y<c&&map[nnext.x][nnext.y]!='#'&&fire[nnext.x][nnext.y]==-1)
{
fire[nnext.x][nnext.y]=fire[start.x][start.y]+1;
q.push(nnext);
}
*/
if (nnext.x < 0 || nnext.x >= r || nnext.y < 0 || nnext.y >= c) continue;
if (map[nnext.x][nnext.y] == '#') continue;
if (fire[nnext.x][nnext.y] != -1) continue;
fire[nnext.x][nnext.y] = fire[start.x][start.y] + 1;
q.push(nnext);
}
}
// for(int i=0;i<r;i++)
// {
// for(int j=0;j<c;j++)
// cout<<fire[i][j];
// cout<<endl;
// }
}
int jj_bfs(node jj) {
memset(vis, -1, sizeof(vis));
queue<node> q;
vis[jj.x][jj.y] = 0;
q.push(jj);
while (!q.empty()) {
start = q.front();
q.pop();
if (start.x == 0 || start.x == r - 1 || start.y == 0 || start.y == c - 1)
return vis[start.x][start.y] + 1;
for (int i = 0; i < 4; i++) {
nnext.x = start.x + dis[i][0];
nnext.y = start.y + dis[i][1];
/**
if((fire[nnext.x][nnext.y]!=-1&&vis[start.x][start.y]+1<fire[nnext.x][nnext.y])||fire[nnext.x][nnext.y]==-1)
if(nnext.x>=0&&nnext.y>=0&&nnext.x<r&&nnext.y<c&&map[nnext.x][nnext.y]!='#'&&vis[nnext.x][nnext.y]==-1)
{
vis[nnext.x][nnext.y]=vis[start.x][start.y]+1;
q.push(nnext);
}
*/
if (nnext.x < 0 || nnext.x >= r || nnext.y < 0 || nnext.y >= c) continue;
if (map[nnext.x][nnext.y] == '#') continue;
if (vis[nnext.x][nnext.y] != -1) continue;
if (fire[nnext.x][nnext.y] != -1 && vis[start.x][start.y] + 1 >= fire[nnext.x][nnext.y]) continue;
vis[nnext.x][nnext.y] = vis[start.x][start.y] + 1;
q.push(nnext);
}
}
// for(int i=0;i<r;i++)
// {
// for(int j=0;j<c;j++)
// cout<<vis[i][j];
// cout<<endl;
// }
return -1;
}
int main() {
int t;
cin >> t;
while (t--) {
cin >> r >> c;
for (int i = 0; i < r; i++)
for (int j = 0; j < c; j++) {
cin >> map[i][j];
if (map[i][j] == 'J') {
jj.x = i, jj.y = j;
}
}
ff_bfs(ff);
int time = jj_bfs(jj);
if (time == -1)
cout << "IMPOSSIBLE" << endl;
else
cout << time << endl;
}
return 0;
}