• Codeforces Round #648 (Div. 2) D. Solve The Maze


    这题犯了一个很严重的错误,bfs 应该在入队操作的同时标记访问,而不是每次只标记取出的队首元素。

    题目链接:https://codeforces.com/contest/1365/problem/D

    题意

    有一个 $n imes m$ 的迷宫,迷宫有四种方格:

    • '.' 空方格
    • '#' 墙
    • 'B' 坏人
    • 'G' 好人

    人与人间可以通行,人与墙间不能,可以把任意空方格变为墙,问能否所有好人可以到达 $(n, m)$ 但所有坏人不能。

    题解

    无解有两种情况:

    • 坏人与好人相邻
    • 在每个坏人相邻的四个方格建墙后有好人不能到达终点

    用 bfs 或 dfs 模拟即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int dir[4][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
    const int N = 55;
    
    int n, m; 
    char MP[N][N];
    
    bool inside(int x, int y) {
        return (1 <= x and x <= n) and (1 <= y and y <= m);
    }
     
    bool good(int x, int y) {
        return MP[x][y] == '.' or MP[x][y] == 'G';
    }
    
    void bfs() {
        queue<pair<int, int>> que;
        que.push({n, m});
        MP[n][m] = 'E';
        while (!que.empty()) {
            int x = que.front().first;
            int y = que.front().second;
            que.pop();
            for (int i = 0; i < 4; i++) {
                int nx = x + dir[i][0];
                int ny = y + dir[i][1];
                if (inside(nx, ny) and good(nx, ny)) {
                    que.push({nx, ny});
                    MP[nx][ny] = 'E';
                }
            }
        }
    }
    
    void solve() {
        cin >> n >> m;
        vector<pair<int, int>> G, B;
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                cin >> MP[i][j];
                if (MP[i][j] == 'G') G.push_back({i, j});
                if (MP[i][j] == 'B') B.push_back({i, j});
            }
        }
        bool block = true;
        for (auto pr : B) {
            int x = pr.first;
            int y = pr.second;
            for (int i = 0; i < 4; i++) {
                int nx = x + dir[i][0];
                int ny = y + dir[i][1];
                if (MP[nx][ny] == 'G') block = false;
                if (MP[nx][ny] == '.') MP[nx][ny] = '#';
            }
        }
        if (good(n, m)) bfs();
        bool escape = true;
        for (auto pr : G)
            escape &= MP[pr.first][pr.second] == 'E';
        cout << (block and escape ? "Yes" : "No") << "
    ";
    }
    
    int main() {
        int t; cin >> t;
        while (t--) solve();
    }
  • 相关阅读:
    java10 var
    java lambda,方法引用
    Java集合总结
    Oracle/Sun JDK与OpenJDK的区别和联系
    IO基本知识
    字符串反转2单词内部不进行转换
    反转String 1
    java 左移<<&>>右移&>>无符号右移
    反射
    equals方法与hashcode方法
  • 原文地址:https://www.cnblogs.com/Kanoon/p/13063336.html
Copyright © 2020-2023  润新知