zoukankan      html  css  js  c++  java
  • UVA 11624 Fire!

    题目大意:

    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
    ", 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
    ");//未满足条件
    
    }
    
    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
    */
  • 相关阅读:
    ARM-Linux S5PV210 UART驱动(1)----用户手册中的硬件知识
    可变参数列表---以dbg()为例
    《C和指针》 读书笔记 -- 第7章 函数
    《Visual C++ 程序设计》读书笔记 ----第8章 指针和引用
    支持异步通知的globalfifo平台设备驱动程序及其测试代码
    linux内核中sys_poll()的简化分析
    《C和指针》读书笔记——第五章 操作符和表达式
    测试方法-等价类划分法
    MonkyTalk学习-8-Agent
    MonkyTalk学习-7-Verify-Verify
  • 原文地址:https://www.cnblogs.com/wangyuhao/p/4688069.html
Copyright © 2011-2022 走看看