题解:火的数目不一定唯一,所以遍历地图将火的位置加入队列,bfs1数组搜索火达到某一点的时间,
然后用bfs搜索如何出去,当到达某一点如果_time不为INF那么如果step大于time,那么火已经到达这一点,不能加入队列,如果time为INF那么可以到达,直到走出迷宫,或者走不出去
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<string>
#include<queue>
#include<cstring>
#include<stack>
#include<vector>
using namespace std;
const int INF = 0x3f3f3f3f;
int n, m,t;
int bx, by;
int vis[1010][1010];
int _time[1010][1010];
char map[1010][1010];
int dir[4][2] = { 0, 1, 0, -1, 1, 0, -1, 0 };
bool checkedge(int x,int y){
if (map[x][y] == '#' || x<1 || x>n || y<1 || y>m || vis[x][y])
return 1;
return 0;
}
struct node{
int x, y;
int step;
};
queue<node>q;
void bfs1(){//记录火达到某一点的时间
while (!q.empty()){
node now = q.front();
q.pop();
int nx, ny;
for (int i = 0; i < 4; i++){
nx = now.x + dir[i][0];
ny = now.y + dir[i][1];
if (checkedge(nx, ny)) continue;
_time[nx][ny] = _time[now.x][now.y] + 1;
vis[nx][ny] = 1;
q.push({ nx, ny, now.step + 1 });
}
}
}
void bfs(int x, int y){//bfs走迷宫就行
node now;
now.x = x;
now.y = y;
now.step = 0;
q.push(now);
vis[x][y] = 1;
while (!q.empty()){
now = q.front();
q.pop();
if (now.x == 1 || now.y == 1 || now.x == n || now.y == m){
cout << now.step + 1 << endl;
return;
}
int nx, ny;
for (int i = 0; i < 4; i++){
nx = now.x + dir[i][0];
ny = now.y + dir[i][1];
if (map[nx][ny] == '#' || vis[nx][ny] || (now.step + 1) >= _time[nx][ny])//火先到达
continue;
vis[nx][ny] = 1;
q.push({ nx, ny, now.step + 1 });
}
}
cout << "IMPOSSIBLE" << endl;//走不出来
return;
}
int main(){
ios::sync_with_stdio(false);
cin >> t;
while (t--){
cin >> n >> m;
memset(vis, 0, sizeof vis);
memset(_time, 0x3f, sizeof _time);
for (int i = 1; i <= n; i++)
cin >> map[i] + 1;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++){
if (map[i][j] == 'J')
bx = i, by = j;
if (map[i][j] == 'F'){
q.push({ i, j, 0 });//如果为火加入队列,然后搜时间
_time[i][j] = 0;//初始化
vis[i][j] = 1;
}
}
bfs1();
while (!q.empty()) q.pop();//清空
memset(vis, 0, sizeof vis);//初始化
bfs(bx, by);
}
return 0;
}