题目大意:
F代表火焰
J代表人
一个人想在火焰烧到自己之前逃出着火地区
. 为路,人可以走,火可以燃烧(当然如果火先烧到就不能走了)
#为墙,不可走
如果能逃出,输出时间,不能,输出IMPOSSIBLE
每次移动上下左右(人火都是, 花费1)
解题思路:
简单广搜两次就行,先对火广搜,保存下步数,在对人广搜,看看走到此点花费的时间是不是比火小,小的话可以走,不然不能走,走到边界为逃出条件
具体实现用一个二维数组F
先对火焰进行广搜,用来保存每个点火燃烧到时花费的步数,初始值为0;
第二次广搜人走到此点需要的步数,如果小于此时此点保存的则证明可以走,走过之后赋值为-1;
火燃烧出发点赋值为-1;
代码:
#include <iostream>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack> using namespace std;
#define INF 0xfffffff
#define N 1010
int m, n;
char maps[N][N];
int dir[][] = {,, ,-, ,, -,};
int F[N][N];
/*F, 先对火焰进行广搜,用来保存每个点火燃烧到时花费的步数,初始值为0;
第二次广搜人走到此点需要的步数,如果小于此时此点保存的则证明可以走,走过之后赋值为-1;
火燃烧出发点赋值为-1,
*/ struct node
{
int x, y;
int step;
}s, e, a[N], q1; void Init()//初始化
{
memset(maps, , sizeof(maps));
memset(F, , sizeof(F));
memset(a, , sizeof(a));
} void BFS(int c)
{
queue<node>q; for(int i = ; i < c; i++) {
q.push(a[i]);
F[a[i].x][a[i].y] = -;
} while(q.size()) {//对火焰的广搜
q1 = q.front();
q.pop(); for(int i = ; i < ; i++) {
e.x = q1.x + dir[i][];
e.y = q1.y + dir[i][];
e.step = q1.step + ;
if(e.x >= && e.y >= && e.x < m && e.y < n && F[e.x][e.y] == && maps[e.x][e.y] == '.') {
F[e.x][e.y] = e.step;
q.push(e);
}
}
} q.push(s);
F[s.x][s.y] = -; while(q.size()) {//对人的广搜
q1 = q.front();
q.pop();
if(q1.x == || q1.y == || q1.x == m - || q1.y == n - ) {//达到出去条件, 输出到达此地步数+1
printf("%d\n", q1.step + );
return;
} for(int i = ; i < ; i++) {
e.x = q1.x + dir[i][];
e.y = q1.y + dir[i][];
e.step = q1.step + ;
if(c != ){
if(e.x >= && e.y >= && e.x < m && e.y < n && F[e.x][e.y] != - && e.step < F[e.x][e.y] && maps[e.x][e.y] == '.') {
F[e.x][e.y] = -;
q.push(e);
}
}
else if(e.x >= && e.y >= && e.x < m && e.y < n && F[e.x][e.y] != - && maps[e.x][e.y] == '.') {
F[e.x][e.y] = -;
q.push(e);
}
} } printf("IMPOSSIBLE\n");//未满足条件 } int main()
{
int T;
scanf("%d", &T);//T个样例 while(T--) {
Init();//初始化
int c = ;
scanf("%d %d", &m, &n);
for(int i = ; i < m; i++) {
scanf(" ");
for(int j = ; j < n; j++) {
scanf("%c", &maps[i][j]);
if(maps[i][j] == 'F') {//读入数据同时进行初始化 保存人和火焰的下标
a[c].x = i;
a[c].y = j;
a[c++].step = ;
}
if(maps[i][j] == 'J') {
s.x = i;
s.y = j;
s.step = ;
}
}
}
BFS(c);//开广搜 }
}
/*
2
4 4
####
#J.#
#..#
#..#
3 3
###
#J.
#.F
*/