Description
给定一张 (n imes m) 的网格图,每个格子可能是好的也可能是坏的,坏的走了就会结束,好的走了就会变成坏的。现在要求从起点出发,走到终点并在终点结束(意味着如果终点是好的那么需要经过一次后再到达)。求能否完成。
Solution
如果终点是坏的,那么可以完成当且仅当存在一条到达终点的路径。
如果终点是好的,那么可以完成当且仅当终点的四相邻格子中至少有两个 (p,q) 满足存在一条从起点分别到达 (p,q) 的路径。
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
int n, m;
cin >> n >> m;
vector<vector<int>> a(n + 2);
for (auto &i : a)
{
i.resize(m + 2);
}
for (int i = 1; i <= n; i++)
{
string tmp;
cin >> tmp;
for (int j = 1; j <= m; j++)
{
a[i][j] = tmp[j - 1] == 'X';
}
}
vector<vector<int>> vis(n + 2);
for (auto &i : vis)
i.resize(m + 2);
const int di[] = {0, 0, 1, -1};
const int dj[] = {1, -1, 0, 0};
function<bool(int, int)> check = [&](int i, int j) -> bool {
return i >= 1 && j >= 1 && i <= n && j <= m;
};
function<void(int, int)> dfs = [&](int i, int j) -> void {
vis[i][j] = 1;
for (int k = 0; k < 4; k++)
{
int ni = i + di[k];
int nj = j + dj[k];
if (check(ni, nj) && a[ni][nj] == 0 && vis[ni][nj] == 0)
{
dfs(ni, nj);
}
}
};
int si, sj, ti, tj;
cin >> si >> sj >> ti >> tj;
dfs(si, sj);
int cnt = 0;
for (int k = 0; k < 4; k++)
{
int ni = ti + di[k];
int nj = tj + dj[k];
if (check(ni, nj) && vis[ni][nj])
{
++cnt;
}
}
if (cnt >= 2 || (cnt >= 1 && a[ti][tj]))
{
cout << "YES" << endl;
}
else
{
cout << "NO" << endl;
}
}