您的位置:首页 > 其它

UVA 11624 Fire!

2015-07-30 07:51 495 查看
题目大意:

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

;
int dir[4][2] = {0,1, 0,-1, 1,0, -1,0};
int F

;
/*F, 先对火焰进行广搜,用来保存每个点火燃烧到时花费的步数,初始值为0;
第二次广搜人走到此点需要的步数,如果小于此时此点保存的则证明可以走,走过之后赋值为-1;
火燃烧出发点赋值为-1,
*/

struct node
{
int x, y;
int step;
}s, e, a
, 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
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: