zoukankan      html  css  js  c++  java
  • UVA

    UVA - 11624

    题意:joe在一个迷宫里,迷宫的一些部分着火了,火势会向周围四个方向蔓延,joe可以向四个方向移动。火与人的速度都是1格/1秒,问j能否逃出迷宫,若能输出最小时间。

    题解:先考虑模拟火,肯定是bfs(每次把同一时间着火的格子pop出来,再将它们周围的格子的t加一push进去)

        然后考虑怎么模拟人,现在人处在一个会变化的迷宫中。貌似很复杂。

        我们可以考虑t时刻的地图(假设我们bfs人的位置),着火的地方相当于墙壁,已经走过的地方也相当于墙壁(因为不可能回到已经走过的地方,这样要么出不去,要么走了回头路导致时间变长)。队列中存着当前时刻所有人可以到达的位置。考虑我们可以走的位置,除了边界与墙壁,如果我们知到一秒后哪些位置会着火,我们就不会走那些格子(否则就烧死了)。

    于是便得到了一个算法,先让火烧一秒,然后人bjs一步,再烧1秒,再走一步。。。。

    坑:一开始我先让人走一步,结果完全无法模拟人被火烧到的情况;

         用queue的的时候老报错,总是pop空栈(因为没有考虑第一个与同一时刻的最后一个的特殊情况,结果写了一个很混乱的逻辑判断)

    正确的方法是:

    f v = F.front();
    if (v.t == t) {...} else{return;}

    #define  _CRT_SECURE_NO_WARNINGS
    #include<cstdio>  
    #include<algorithm>  
    #include<iostream>
    #include<string>
    #include<vector>
    #include<string.h>
    #include<queue>
    using namespace std;
    typedef long long ll;
    const int maxn = 10000 + 5;
    //模拟F,深搜J,
    //F有多个,J一个
    struct f {
        int x, y, t;
        f(int x = 0, int y = 0, int t = 0) :x(x), y(y), t(t) {}
    };
    int dir[4][2] = { 0,1, 0,-1, 1,0, -1,0 };
    char map[maxn][maxn];
    int  vis[maxn][maxn], fired[maxn][maxn];
    queue<f > F, J;
    int R, C; int flag = 1; int cnt = 0, square = 0; int T = 0;
    bool check(int x, int y) {
        if (map[x][y] == '#' || R < x || x <= 0 || y <= 0 || C < y)return 1;
        else return 0;
    }
    void spread(int t) {//fire at (x,y) spread.//bfs1层
    
        while (!F.empty()) {
            f v = F.front();
            if (v.t == t) {
                map[v.x][v.y] = '#';
                F.pop();
                for (int i = 0; i < 4; i++) {
                    int dx = v.x + dir[i][0], dy = v.y + dir[i][1];
                    if (check(dx, dy))continue;
                    map[dx][dy] = '#';
                    F.push(f(dx, dy, v.t + 1));
                }
            }
            else return;
        }
    }
    void bfs(int t) {//J runs at t
        while (!J.empty()) {
            f v = J.front();
            if (v.t == t) {
                J.pop();
                for (int i = 0; i < 4; i++) {
                    int dx = v.x + dir[i][0], dy = v.y + dir[i][1];
                    if (dx <= 0 || dx > R || dy <= 0 || dy > C) { flag = v.t + 1; while (!J.empty())J.pop(); return; }
                    if (map[dx][dy] != '#') {
                        map[dx][dy] = '#';
                        J.push(f(dx, dy, v.t + 1));
                    }
                }
            }
            else return;
        }
    }
    int main() {
        int t; cin >> t;
        while (t--) {
            while (!J.empty())J.pop();
            while (!F.empty())F.pop();
            cin >> R >> C;
            for (int i = 1; i <= R; i++) {
                scanf("%s", map[i] + 1);
                for (int j = 1; j <= C; j++)if (map[i][j] == 'F') F.push(f(i, j, 0)), fired[i][j] = 1; else if (map[i][j] == 'J')J.push(f(i, j, 0)), map[i][j] = '#';
            }
            flag = -1;
            T = 0;
            int tf = 0, tj = 0;
            while (!J.empty()) {
                spread(T);
                bfs(T);
                T++;
                if (flag > 0)break;
            }
    
            if (flag == -1)cout << "IMPOSSIBLE" << endl;
            else cout << flag << endl;
        }
        cin >> t;
    }

     同学的想法是两次bfs,先bfs一次火的,把它抵达各个格子的时间填在一个表里,说明人在这个时间之后就不能走到这里了,把这个判断加到人的bfs里面即可

            #define _CRT_SECURE_NO_WARNINGS
            #include <iostream>
            #include <cstdio>
            #include <algorithm>
            #include <queue>
            #include <vector>
            #include <string.h>
    
            using namespace std;
            char map[1005][1005];
            int vis[1005][1005];
            int tf[1005][1005];
            int n, m, ji, jj, fi, fj;
            struct Node {
                int i, j;
                Node(int i = 0, int j = 0) :i(i), j(j) {}
            };
            queue<Node>q;
            int dir[4][2] = { { 1,0 },{ -1,0 },{ 0,1 },{ 0,-1 } };
            void bfsf() {
                while (!q.empty()) {
                    Node t = q.front();
                    q.pop();
                    for (int k = 0; k<4; k++) {
                        int di = t.i + dir[k][0];
                        int dj = t.j + dir[k][1];
                        if (di<0 || di >= n || dj<0 || dj >= m || map[di][dj] == '#' || tf[di][dj] != -1) continue;
                        q.push(Node(di, dj));
                        tf[di][dj] = tf[t.i][t.j] + 1;
                    }
                }
            }
    
            int bfsj(int i, int j) {
                queue<Node>que;
                que.push(Node(i, j));
                vis[i][j] = 0;
                while (!que.empty()) {
                    Node t = que.front();
                    que.pop();
                    if (t.i == 0 || t.i == n - 1 || t.j == 0 || t.j == m - 1)
                        return vis[t.i][t.j] + 1;
                    for (int k = 0; k<4; k++) {
                        int di = t.i + dir[k][0];
                        int dj = t.j + dir[k][1];
                        if (di<0 || di >= n || dj<0 || dj >= m || map[di][dj] == '#' || (vis[di][dj] != -1 || vis[t.i][t.j] + 1 >= tf[di][dj]&&tf[di][dj]>0)) continue;
                        que.push(Node(di, dj));
                        vis[di][dj] = vis[t.i][t.j] + 1;
                    }
                }
                return -1;
            }
            int main() {
                int t;
                scanf("%d", &t);
                while (t--) {
                    memset(tf, -1, sizeof(tf));
                    scanf("%d%d", &n, &m);
                    for (int i = 0; i<n; i++) {
                        scanf("%s", map[i]);
                        for (int j = 0; j<m; j++) {
                            if (map[i][j] == 'J') ji = i, jj = j;
                            if (map[i][j] == 'F') q.push(Node(i, j)), tf[i][j] = 0;
                        }
                    }
                    bfsf();
                    /*for (int i = 0; i < n; i++) {
                        for (int j = 0; j <= m; j++) cout << tf[i][j] << ' '; cout << endl;
                    }*/
    
                    memset(vis, -1, sizeof(vis));
                    int ans = bfsj(ji, jj);
                    if (ans == -1) printf("IMPOSSIBLE
    ");
                    else printf("%d
    ", ans);
            
                }
                return 0;
            }
    成功的路并不拥挤,因为大部分人都在颓(笑)
  • 相关阅读:
    webyestem(伊莱博)票据管理(ver1.0)数据库设计
    MicrosoftNorthwind(电子商务)数据库设计
    WebForm三层架构
    WebForm带接口工厂模式的三层架构
    VS 2008 C#代码调试进C++代码设置/远程调试
    C# 中使用指针
    互操作性——使用C/C++类型的非托管函数基础
    Perforce使用指南_forP4V
    [转]DotNet程序之找BUG心得
    C# 对XML基本操作总结
  • 原文地址:https://www.cnblogs.com/SuuT/p/8616564.html
Copyright © 2011-2022 走看看