今天打卡大模拟
Problem - 1365D - Codeforces
大模拟确实恶心人,但作为最臭的屎平时还是得多吃点,大模拟的特点是思路不算很难但代码真的很长很长,一个不小心哪里写得有问题查错就是半天,各种细节都要很注意,对于提升自己查错能力和快速写题能力还是很有帮助的,这种屎虽然恶心但是就是得多吃。
简单说下题意,大概就是给定一个网格图,网格图有四种符号,#代表墙,B代表bad坏人,G代表good好人, "."代表空白,可以把一些空白变成墙,然后使所有好人能跑走,坏人留下,并且只有跑到[n,m]才算逃出生天。
思路很简单,就是把所有坏人都关起来,好人不能和坏人相邻,并且好人没有被关起来的。
代码实现
#include <bits/stdc++.h>
using namespace std;
const char nl = '\n';
#define all(x) (x).begin(), (x).end()
typedef long long ll;
typedef long double ld;
typedef long long int lli;
const int MOD = 1'000'000'007;
constexpr int inf = 1e9;constexpr int dx[] = {0, 0, -1, 1}, dy[] = {-1, 1, 0, 0};void solve()
{int n, m;cin >> n >> m;vector<string> a(n);int res = 0;for (int i = 0; i < n; i++){cin >> a[i];res += count(a[i].begin(), a[i].end(), 'G');}if (res == 0){cout << "YES" << nl;return;}a[n - 1][m - 1] = 'G';for (int i = 0; i < n; i++){for (int j = 0; j < m; j++){if (a[i][j] == 'B'){for (int k = 0; k < 4; k++){int x = j + dx[k], y = i + dy[k];if (x < m && x >= 0 && y >= 0 && y < n){if (a[y][x] == 'G'){cout << "NO" << nl;return;}if (a[y][x] == '.'){a[y][x] = '#';}}}}}}vector<vector<bool>> vis(n, vector<bool>(m));queue<pair<int, int>> q;vis[n - 1][m - 1] = 1;q.emplace(n - 1, m - 1);while (!q.empty()){auto [i, j] = q.front();q.pop();for (int k = 0; k < 4; ++k){int x = i + dx[k], y = j + dy[k];if (0 <= x && x < n && 0 <= y && y < m && a[x][y] != '#' && !vis[x][y]){vis[x][y] = true;q.emplace(x, y);}}}for(int i = 0;i < n;i++){for(int j = 0;j < m;j++){if(a[i][j] == 'G' && !vis[i][j]){cout << "NO" << nl;return;}}}cout << "YES" << nl;
}int main()
{ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);int t = 1;cin >> t;while (t--){solve();}return 0;
}
代码的思路就是先查找有没有好人,如果没有就直接把出口堵上就好了所以肯定是yes因为题目保证了出口是空白
其次是把最后的位置变为一个好人,因为当好人和坏人分别在出口的上方和左方时是不行的,直接把这种情况算到好人和坏人相邻就行,然后查找好人与坏人相邻的情况,并且把所有坏人都关上。
最后是从出口开始查找对于所有通出口的地方都标记为1,所有不通的地方都标为0,然后查找好人被关的情况就行。