codeforces1365D
题意:
有一个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;
}