bfs做,注意是每一搜完一层,火才会蔓延一层,并不是每一次搜索都会蔓延一层。
ac code:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int M=1005;
struct node{
int x,y;
int step;
};
struct fire{
int x,y;
};
int n,m;
char map[M][M];
bool divs[M][M];
fire record[M*M];
node s;
queue <node> q;
int dire[4][2]={0,1,1,0,-1,0,0,-1};
int k;
int limi_down;
void init()
{
k=0;
limi_down=1;
memset(map,'.',sizeof(map));
memset(divs,0,sizeof(divs));
while(!q.empty()) q.pop();
for(int i=1;i<=n;++i)
{
scanf("%s",map[i]+1);
for(int j=1;j<=m;++j)
{
if(map[i][j]=='F')record[++k].x=i,record[k].y=j,divs[i][j]=1;
else if(map[i][j]=='J') s.x=i,s.y=j,s.step=0,divs[i][j]=1;
else if(map[i][j]=='#')divs[i][j]=1;
}
}
}
bool check(int x,int y)
{
if(x<=n&&x>=1&&y<=m&&y>=1&&map[x][y]=='.')return 1;
else return 0;
}
void frie_extend()
{
int limi_up=k;
int x,y;
for(int i=limi_down;i<=limi_up;++i)
{
for(int j=0;j<4;++j)
{
x=record[i].x+dire[j][0];
y=record[i].y+dire[j][1];
if(check(x,y))
{
map[x][y]='F';
divs[x][y]=1;
record[++k].x=x,record[k].y=y;
}
}
}
limi_down=limi_up+1;
}
void bfs()
{
node t,tt;
int len;
while(!q.empty())
{
frie_extend();
len=q.size();
while(len)
{
len--;
t=q.front();
q.pop();
if(t.x<1||t.x>n||t.y<1||t.y>m)
{
cout<<t.step<<endl;
return ;
}
for(int i=0;i<4;++i)
{
tt.x=t.x+dire[i][0];
tt.y=t.y+dire[i][1];
if(divs[tt.x][tt.y]==0)
{
tt.step=t.step+1;
divs[tt.x][tt.y]=1;
q.push(tt);
}
}
}
}
cout<<"IMPOSSIBLE\n";
}
int main()
{
int T;
while(cin>>T)
{
while(T--)
{
cin>>n>>m;
init();
q.push(s);
bfs();
}
}
}