如果你还不知道火可能会有很多的话,快点回去吧,改一改说不定就是正确答案了
(博主一直以为同时BFS不对而被迫去看了两次的答案才知道QAQ)
这道题看到了肯定知道要用bfs,其实我的第一感觉也是想用两次BFS,但感觉那样
有点太模板了,于是写了一个人与火同步的BFS
大致思路:
用一个struct 去存信息 (位置x,y) (id==1?人:火) (d:只表示人的已走步数(对于火没有意义))
c1是标记人是否走过,c2是标记火是否到达
对于每一秒,也就是这一秒中所有人该走的路以及火该走的路,先走人的再走火的
例如 ####
#JF.
#..#
#..# 如果先让火走那直接会把人的初始位置标记,那就出不去了
(这里的先后也并非真正意义上的先后,只是营造了一种火追人的情况,即使是人先走,走时也要判断这里有没有被火标标记,而燃到的也都是前一秒的火)
对于人:先判断此时这里有火吗(if(c2[x1.x][x1.y] == 1) continue;)
其实/*1*/处的c2[x1.x][x1.y]==0
与/*2*/处的if(c2[x1.x][x1.y] == 1) continue;都是等价的,及人将要走时,先判断一下上一次人走过后火有没有追上
然后在判断延展对于人来说C1,C2都要判断,对于火来说只用判断C2
对于火:就是正常判断再向四周延展
因为火的顺序在人之后,这里再输入时把每一个火先存到q2里面,等到把人的初始位置输入之后,再循环输入
#include <iostream>
#include <string.h>
#include <limits.h>
#include <queue>
using namespace std;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int ans,xs,ys,xe,ye,C,R,c1[1100][1100],c2[1100][1100];
char s[1100][1100];
struct node{
int x;
int y;
int id;
int d;
};
queue<node> qq,q2;
bool bfs(){
queue<node> q;
node x1,x2;
x1.x=xs,x1.y=ys,x1.id=1,x1.d=0;
c1[xs][ys]=1;
q.push(x1);
while(q2.size()){#把火再存到q里面
x2=q2.front();
q2.pop();
q.push(x2);
}
while(q.size()){
x1=q.front();
q.pop();
if(x1.id==1&&(x1.x==0||x1.x==R-1||x1.y==0||x1.y==C-1)&&c2[x1.x][x1.y]==0){
ans=x1.d+1;
return true;
}
if(x1.id==1){
if(c2[x1.x][x1.y] == 1) continue;
for(int i = 0 ; i < 4 ; i++){
int tx=x1.x+dx[i];
int ty=x1.y+dy[i];
if(tx>=0&&tx<R&&ty>=0&&ty<C&&c1[tx][ty]==0&&s[tx][ty]!='#'&&c2[tx][ty]==0){
node x;
x.x=tx,x.y=ty,x.id=1,x.d=x1.d+1;
q.push(x);
c1[tx][ty]=1;
}
}
}
else{
for(int i = 0 ; i < 4 ; i++){
int tx=x1.x+dx[i];
int ty=x1.y+dy[i];
if(tx>=0&&tx<R&&ty>=0&&ty<C&&s[tx][ty]!='#'&&c2[tx][ty]==0){
node x;
x.x=tx,x.y=ty,x.id=2,x.d=0;
q.push(x);
c2[tx][ty]=1;
}
}
}
}
return false;
}
int main()
{
int t;
cin >> t;
while(t--){
memset(c1,0,sizeof(c1));
memset(c2,0,sizeof(c2));
q2=qq;
bool f;
cin >> R >> C;
for(int i = 0 ; i < R; i++){
for(int j = 0 ; j < C; j++){
cin >> s[i][j];
if(s[i][j] == 'J'){
xs=i,ys=j;
}
if(s[i][j]=='F'){
node x;
x.x=i,x.y=j,x.id=2,x.d=0;
q2.push(x);#把火都存到q2里面
c2[i][j]=1;
}
}
}
f=bfs();
if(f){
cout << ans << endl;
}
else{
cout << "IMPOSSIBLE" << endl;
}
}
return 0;
}