题目:一个平面迷宫中有一个人,迷宫中有些点起火了,火和人每个单位时间只能向相邻的格子移动,
其中有一些空间被墙壁占据,问这个人在不背或烧到的情况下,离开迷宫的最快时间。
题解:现对火进行bfs,预处理出火燃烧的状态,然后对人进行bfs,判断当前能否走到该点上,即该点是否有火在燃烧。预处理火的时候,直接全部添加进队列中,一开始一个个bfs的时候T了。。。。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <vector>
#include <set>
#include <list>
#include <queue>
#include <map>
using namespace std;
#define L(i) i<<1
#define R(i) i<<1|1
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-4
#define maxn 100010
#define MOD 1000000007
char s[1010][1010];
int vis[1010][1010],fire[1010][1010];
int n,m,sx,sy;
int mx[4] = {0,0,1,-1};
int my[4] = {1,-1,0,0};
struct node
{
int x,y,t;
} st,ss;
queue<pair<int,int> > Q;
void bfs_fire()
{
while(!Q.empty())
{
int xx = Q.front().first;
int yy = Q.front().second;
Q.pop();
for(int i = 0; i < 4; i++)
{
int dx = xx + mx[i];
int dy = yy + my[i];
if(dx < 0 || dx >= n || dy < 0 || dy >= m)
continue;
if(s[dx][dy] == '#' || vis[dx][dy])
continue;
vis[dx][dy] = 1;
fire[dx][dy] = fire[xx][yy] + 1;
Q.push(make_pair(dx,dy));
}
}
}
void bfs()
{
memset(vis,0,sizeof(vis));
queue<node> q;
st.x = sx;
st.y = sy;
st.t = 0;
vis[sx][sy] = 1;
q.push(st);
while(!q.empty())
{
st = q.front();
q.pop();
//printf("%d %d\n",st.x,st.y);
for(int i = 0; i < 4; i++)
{
int dx = st.x + mx[i];
int dy = st.y + my[i];
if(dx < 0 || dx >= n || dy < 0 || dy >= m)
{
printf("%d\n",st.t+1);
return;
}
if(vis[dx][dy] || s[dx][dy] == '#' || st.t+1 >= fire[dx][dy])
continue;
ss.x = dx;
ss.y = dy;
ss.t = st.t + 1;
vis[dx][dy] = 1;
q.push(ss);
}
}
printf("IMPOSSIBLE\n");
}
int main()
{
int t,c = 1;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i = 0; i < n; i++)
scanf("%s",s[i]);
memset(fire,INF,sizeof(fire));
memset(vis,0,sizeof(vis));
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
{
if(s[i][j] == 'F')
{
Q.push(make_pair(i,j));
fire[i][j] = 0;
vis[i][j] = 1;
}
if(s[i][j] == 'J')
{
sx = i;
sy = j;
}
}
bfs_fire();
bfs();
}
return 0;
}