codeforces1365D

1365D

题意:

有一个nm大小的迷宫,#表示墙,.表示空地,b表示坏人,g表示好人,现在要求把空地可以变成墙,问有没有一种方案能够让好人全部走出迷宫,坏人一个也走不出来,坐标(n,m)表示迷宫的出口

思路:

可以把b周围的所有空地全部变成墙 ,然后求其他g能不能出迷宫,这个贪心策略可以这样想,假如b周围有空地,如果g可以经过,那么b一定可以跟着g走,所以需要把b周围全部变成墙;

题解:

判断是否可以走到终点,可以通过终点dfs每个点,看是不是能都到达即可

#include <bits/stdc++.h>
#define eb emplace_back
#define divUp(a,b) (a+b-1)/b
#define mkp(x,y) make_pair(x,y)
#define all(v) begin(v),end(v)
#define int long long
using namespace std;
typedef unsigned long long ull;
typedef pair<int, int> pii;
bool checkP2(int n) {return n > 0 and (n & (n - 1)) == 0;};
const int N = 55;
char g[N][N];
int b, gg, n, m, bl, gl;
bool st[N][N];
int dx[4] = { -1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
void dfs(int x, int y) {
    st[x][y] = true;
    if (g[x][y] == 'B') bl++;
    if (g[x][y] == 'G') gl++;
    for (int i = 0; i < 4; i++) {
        int tx = dx[i] + x, ty = dy[i] + y;
        if (tx >= 1 and ty <= m and tx <= n and ty >= 1 and g[tx][ty] != '#' and !st[tx][ty]) {
            dfs(tx, ty);
        }
    }
}
void solve() {
    cin >> n >> m;
    memset(st, 0, sizeof st);
    gl = gg = b = bl = 0;
    for (int i = 1; i <= n; i++) {
        cin >> (g[i] + 1);
    }
    auto turn = [](int x, int y) {
        for (int i = 0; i < 4; i++) {
            int tx = dx[i] + x, ty = dy[i] + y;
            if (tx >= 1 and ty >= 1 and tx <= n and ty <= m and g[tx][ty] == '.') {
                g[tx][ty] = '#';
            }
        }
    };
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (g[i][j] == 'B') turn(i, j), b++;
            else if (g[i][j] == 'G') gg++;
        }
    }
    dfs(n, m);
    if (gl == gg and bl == 0 or gg == 0) {
        cout << "YES" << endl;
    } else cout << "NO" << endl;
}
signed main() {
    ios::sync_with_stdio(false); cin.tie(0);
    int _; cin >> _; while (_--)
        solve();
    return 0;
}
posted @ 2021-10-07 01:10  指引盗寇入太行  阅读(58)  评论(0编辑  收藏  举报