传送门:
题目大意:
你的任务是帮助Joe走出一个大火蔓延的迷宫。Joe每分钟可以走到上下左右4个方向的相邻格子之一,而所有着火的格子都会四周蔓延(即如果某个空格子与着火格子有公共边,则下一分钟这个空格子将着火)。迷宫中有一些障碍格,Joe和火都无法进入。当Joe走到一个迷宫的边界格子时,我们认为他已经出了迷宫。
输入数据 第一行为数据组数T。每一组测试数据格式如下: 第一行为两个整数R和C(1<=R,C<=1000)。以下R行每行有C个字符,即迷宫,其中“#”表示墙和障碍物,“.”表示空地,“J”是joe的初始位置(也就是空地),”F”是着火格子。每组数据的迷宫中恰好有一个格是”J”。
输出数据 对于每组测试数据,如无法走出迷宫,则输出IMPOSSIBLE,否则输出走出迷宫的最短时间(单位:分钟)。
分析:
本应该是一个标准的最短路,但由于火焰的影响,就要先处理出火焰到改点的时间,这样才能判断人是否能到达该点
ps:1.有多组数据,注意清空
2.一个迷宫中有多个‘F’,同时加入队列即可
3.bfs中ans判断的位置(应该就我这么弱智吧)
代码
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#define IL inline
#define open(s) freopen(s".in","r",stdin); freopen(s".out","w",stdout);
#define close fclose(stdin); fclose(stdout);
using namespace std;
IL int read()
{
char c = getchar();
int sum = 0 ,k = 1;
for(;'0' > c || c > '9'; c = getchar())
if(c == '-') k = -1;
for(;'0' <= c && c <= '9'; c = getchar()) sum = sum * 10 + c - '0';
return sum * k;
}
struct node
{
int x, y;
IL node(int x_ = 0, int y_ = 0)
{
x = x_; y = y_;
}
};
const int maxn = 1000 + 5;
int inf;
bool mp[maxn][maxn];
int fire[maxn][maxn];
int dis[maxn][maxn];
int n, m;
int sx, sy;
queue<node>Q;
int dx[4] = {0, 0, 1, -1}, dy[4] = {1, -1, 0, 0};
void bfs1()
{
int x, y;
node p;
for(; !Q.empty();)
{
p = Q.front(); Q.pop();
for(int i = 0; i < 4; ++i)
{
x = p.x + dx[i]; y = p.y + dy[i];
if(0 < x && x <= n && 0 < y && y <= m && fire[x][y] == inf && !mp[x][y])
{
fire[x][y] = fire[p.x][p.y] + 1;
Q.push(node(x, y));
}
}
}
}
int bfs2()
{
int x, y;
node p;
memset(dis, -1, sizeof(dis));
Q.push(node(sx, sy));
dis[sx][sy] = 1;
for(; !Q.empty();)
{
p = Q.front(); Q.pop();
if(p.x == 1 || p.x == n || p.y == 1 || p.y == m) return dis[p.x][p.y];
for(int i = 0; i < 4; ++i)
{
x = p.x + dx[i]; y = p.y + dy[i];
if(0 < x && x <= n && 0 < y && y <= m && !mp[x][y] && dis[x][y] == -1 && dis[p.x][p.y] + 1 < fire[x][y])
{
dis[x][y] = dis[p.x][p.y] + 1;
Q.push(node(x, y));
}
}
}
return -1;
}
int main()
{
open("11624")
for(int T = read(); T; --T)
{
n = read(); m = read();
for(;!Q.empty(); Q.pop());
memset(mp, 0, sizeof(mp));
memset(fire, 0x3f, sizeof(fire));
inf = fire[0][0];
char c;
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= m; ++j)
{
scanf(" %c", &c);
if(c == 'F')
{
Q.push(node(i, j));
fire[i][j] = 1;
}
if(c == 'J')
{
sx = i; sy = j;
}else
if(c == '#')
mp[i][j] = 1;
}
bfs1();
int k = bfs2();
if(k == -1) printf("IMPOSSIBLE\n"); else printf("%d\n", k);
}
close
return 0;
}