这题真的好多细节问题,我调了好久,感觉自己还是好菜!
言归正传:这题我开始的思路是找到各个火的点,然后一次次bfs去调整各个点的最短蔓延到的时间,但是超时了,后来仔细一想确实,如果点有很多,那就需要很多时间去搜索了。看了大神们的博客后,才明白,其实一次去搜索蔓延时间就可以了。因为这点最短的蔓延时间会由离他最近的火的时间来覆盖,所以就只需要一次。然后我们只要去比较逃到这点的时间火有没有蔓延到就可以了。
#include<bits/stdc++.h>
using namespace std;
#define INF INT_MAX
#define INM INT_MIN
typedef long long LL;
const int N = 1005;
int n,m,vis[N][N],fire[N][N],b[4][2] = {1,0,-1,0,0,1,0,-1},sum,ans;//fire数组存储火势蔓延到这里所需要的时间.
string mp[N];
struct Node
{
int x,y,step;
};
queue<Node> Q1;//优化思路的核心,在输入的时候就把火放入队列
void Cqueue(queue<Node> &Q)//清空队列
{
while(!Q.empty())
{
Q.pop();
}
}
void bfs1()//搜索火势,只需一次
{
Node p,q;
while(!Q1.empty())
{
q = Q1.front();
Q1.pop();
for(int i=0;i<4;++i)
{
int px = q.x+b[i][0];
int py = q.y+b[i][1];
if(px >= 0 && px < n && py >= 0 && py < m && vis[px][py] != 1 && mp[px][py] != '#')//不是墙就记下他的最短被蔓延到的时间
{
vis[px][py] = 1;
fire[px][py] = min(fire[px][py],q.step+1);//覆盖最短的蔓延时间
p.x = px;
p.y = py;
p.step = q.step+1;
Q1.push(p);
}
}
}
return ;
}
int check(int x,int y)//判断是不是在边缘
{
if(x == 0 || x == n-1 || y == 0 || y == m-1) return 1;
return 0;
}
int bfs2(int x,int y)//对能否逃出的搜索
{
memset(vis,0,sizeof(vis));
Node p,q;
queue<Node> Q;
vis[x][y] = 1;
p.x = x;p.y = y;p.step = 0;
Q.push(p);
while(!Q.empty())
{
q = Q.front();
Q.pop();
if(check(q.x,q.y) == 1 && q.step < fire[q.x][q.y])//判断这时候火有没有蔓延到
{
ans = q.step+1;
return 1;
}
for(int i=0;i<4;++i)
{
int px = q.x+b[i][0];
int py = q.y+b[i][1];
if(px >= 0 && px < n && py >= 0 && py < m && vis[px][py] != 1 && mp[px][py] == '.')
{
if(q.step+1 < fire[px][py])//火势没有被蔓延到
{
vis[px][py] = 1;
p.x = px;p.y = py;p.step = q.step+1;
Q.push(p);
}
}
}
}
return 0;
}
int main()
{
ios::sync_with_stdio(false);
int t,si,sj;
Node p;
cin >> n >> m;
int x = 0;
Cqueue(Q1);
for(int i=0;i<n;++i)
for(int j=0;j<m;++j) fire[i][j] = INF;//开始全部都蔓延不到,记为正无穷
memset(vis,0,sizeof(vis));//这里不要忘记重置,这个细节调了好久..
for(int i=0;i<n;++i)
{
cin >> mp[i];
for(int j=0;j<m;++j)
{
if(mp[i][j] == 'J'){si = i;sj = j;}
if(mp[i][j] == 'F')
{
vis[i][j] = 1;//这里就是一次bfs就能搜到所有点的蔓延时间的开始处理
fire[i][j] = 0;//是火就一开始就被蔓延了
p.x = i;p.y = j;p.step = 0;
Q1.push(p);
}
}
}
bfs1();
if(bfs2(si,sj) == 0) printf("IMPOSSIBLE\n");
else
{
printf("%d\n",ans);
}
}