题目大意:
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[4][2] = {0,1, 0,-1, 1,0, -1,0}; int F[N][N]; /*F, 先对火焰进行广搜,用来保存每个点火燃烧到时花费的步数,初始值为0; 第二次广搜人走到此点需要的步数,如果小于此时此点保存的则证明可以走,走过之后赋值为-1; 火燃烧出发点赋值为-1, */ struct node { int x, y; int step; }s, e, a[N], q1; void Init()//初始化 { memset(maps, 0, sizeof(maps)); memset(F, 0, sizeof(F)); memset(a, 0, sizeof(a)); } void BFS(int c) { queue<node>q; for(int i = 0; i < c; i++) { q.push(a[i]); F[a[i].x][a[i].y] = -1; } while(q.size()) {//对火焰的广搜 q1 = q.front(); q.pop(); for(int i = 0; i < 4; i++) { e.x = q1.x + dir[i][0]; e.y = q1.y + dir[i][1]; e.step = q1.step + 1; if(e.x >= 0 && e.y >= 0 && e.x < m && e.y < n && F[e.x][e.y] == 0 && maps[e.x][e.y] == '.') { F[e.x][e.y] = e.step; q.push(e); } } } q.push(s); F[s.x][s.y] = -1; while(q.size()) {//对人的广搜 q1 = q.front(); q.pop(); if(q1.x == 0 || q1.y == 0 || q1.x == m - 1 || q1.y == n - 1) {//达到出去条件, 输出到达此地步数+1 printf("%d\n", q1.step + 1); return; } for(int i = 0; i < 4; i++) { e.x = q1.x + dir[i][0]; e.y = q1.y + dir[i][1]; e.step = q1.step + 1; if(c != 0){ if(e.x >= 0 && e.y >= 0 && e.x < m && e.y < n && F[e.x][e.y] != -1 && e.step < F[e.x][e.y] && maps[e.x][e.y] == '.') { F[e.x][e.y] = -1; q.push(e); } } else if(e.x >= 0 && e.y >= 0 && e.x < m && e.y < n && F[e.x][e.y] != -1 && maps[e.x][e.y] == '.') { F[e.x][e.y] = -1; q.push(e); } } } printf("IMPOSSIBLE\n");//未满足条件 } int main() { int T; scanf("%d", &T);//T个样例 while(T--) { Init();//初始化 int c = 0; scanf("%d %d", &m, &n); for(int i = 0; i < m; i++) { scanf(" "); for(int j = 0; j < n; j++) { scanf("%c", &maps[i][j]); if(maps[i][j] == 'F') {//读入数据同时进行初始化 保存人和火焰的下标 a[c].x = i; a[c].y = j; a[c++].step = 0; } if(maps[i][j] == 'J') { s.x = i; s.y = j; s.step = 0; } } } BFS(c);//开广搜 } } /* 2 4 4 #### #J.# #..# #..# 3 3 ### #J. #.F */