题意:有一个迷宫,迷宫里面有很多火,火蔓延的速度和人的速度是一样的,如果一个格子火先到那么人就不能再走了,问你是否人可以逃出去
题解:先跑一遍bfs把所有火能到的点用一个时间数组tim标记,再跑一次人的bfs判断人到达一个格子是否比火早到,然后判断能否走到迷宫的边缘就行了
#include <iostream>
#include <cstring>
#include <stdio.h>
#include <algorithm>
#include <queue>
using namespace std;
const int mx = 1010;
const int inf = 0x3f3f3f3f;
int r, c;
char mp[mx][mx];
int tim[mx][mx];
bool vis[mx][mx];
int dx[4] = {-1, 1, 0, 0};
int dy[4] = {0, 0, -1, 1};
struct node{
int x, y;
int step;
};
void fireBfs(){
queue<node> qu;
memset(tim, inf, sizeof tim);
memset(vis, 0, sizeof vis);
for(int i = 1; i <= r; i ++){
for(int j = 1; j <= c; j ++){
if(mp[i][j] == 'F'){
vis[i][j] = 1;
tim[i][j] = 1;
node now;
now.x = i, now.y = j;
now.step = 1;
qu.push(now);
}
}
}
while(!qu.empty()){
node now = qu.front();
qu.pop();
for(int i = 0; i < 4; i ++){
int nx = now.x + dx[i];
int ny = now.y + dy[i];
if(mp[nx][ny] != '#' && nx >= 1 && nx <= r
&& ny >= 1 && ny <= c && !vis[nx][ny]){
node nex;
nex.x = nx, nex.y = ny;
nex.step = now.step + 1;
tim[nx][ny] = nex.step;
vis[nx][ny] = 1;
qu.push(nex);
}
}
}
}
int bfs(){
queue<node> qu;
node st;
st.step = 1;
st.x = -1;
for(int i = 1; i <= r; i ++){
for(int j = 1; j <= c; j ++){
if(mp[i][j] == 'J'){
st.x = i, st.y = j;
break;
}
}
if(st.x != -1) break;
}
memset(vis, 0, sizeof vis);
qu.push(st);
while(!qu.empty()){
node now = qu.front();
qu.pop();
if(now.x == 1 || now.x == r || now.y == 1 || now.y == c){
return now.step;
}
for(int i = 0; i < 4; i ++){
int nx = now.x + dx[i];
int ny = now.y + dy[i];
if(mp[nx][ny] != '#' && nx >= 1 && nx <= r
&& ny >= 1 && ny <= c && !vis[nx][ny]
&& now.step + 1 < tim[nx][ny]){
node nex;
nex.x = nx, nex.y = ny;
nex.step = now.step + 1;
vis[nx][ny] = 1;
qu.push(nex);
}
}
}
return -1;
}
int main(){
int t; cin >> t;
while(t --){
memset(tim, 0, sizeof tim);
scanf("%d %d", &r, &c);
for(int i = 1; i <= r; i ++){
string s; cin >> s;
for(int j = 0; j < c; j ++){
mp[i][j + 1] = s[j];
}
}
fireBfs();
int ans = bfs();
if(ans == -1) puts("IMPOSSIBLE");
else cout << ans << endl;
}
return 0;
}