题目大意:

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
*/

 

posted on 2015-07-30 07:51  毕竟我是王宇浩  阅读(207)  评论(0编辑  收藏  举报