题解:P10543 [THUPC2024] 黑白
ChampionCyan · · 题解
P10543题解
首先判定是否有路径从
否则计算有几个选择后仍有路径的点(两个人一共还能选几个点),若数量为奇数则先手胜,否则后手胜。
随后我们发现最初可能有不止一条路径,他们可能长短不同!
没关系,请看:
可以通过染色法得出图中:
标记(或者说颜色)相同的两个点无论怎样“绕路”,最终距离一定为偶数。
标记(或者说颜色)不同的两个点无论怎样“绕路”,最终距离一定为奇数。
因此最终路径长度的奇偶性一定不会发生改变,为了方便,我们直接 BFS 求最短路长度的奇偶性就能得出答案。
code(马蜂自认为好看):
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1001;
const int inf = 0x3f3f3f3f;
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, -1, 0, 1};
inline int read() {
int ret = 0, f = 1;
char ch = getchar();
while (ch < '0' || ch > '9') {
if (ch == '-')
f = -1;
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
ret = (ret << 1) + (ret << 3) + ch - '0';
ch = getchar();
}
return ret * f;
}
int n, m, dis[MAXN][MAXN];
char s[MAXN][MAXN];
bool vis[MAXN][MAXN];
queue<pair<int, int> > q;
inline bool bfs() {
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
dis[i][j] = inf, vis[i][j] = s[i][j] == 'B';
if (vis[1][1])
return false;
dis[1][1] = 1, q.push(make_pair(1, 1));
while (!q.empty()) {
int x = q.front().first, y = q.front().second;
q.pop();
for (int i = 0; i < 4; i++) {
int nx = x + dx[i], ny = y + dy[i];
if (nx < 1 || ny < 1 || nx > n || ny > m || vis[nx][ny])
continue;
q.push(make_pair(nx, ny)), dis[nx][ny] = dis[x][y] + 1, vis[nx][ny] = true;
}
}
return dis[n][m] != inf;
}
int main() {
int t = read();
while (t--) {
n = read(), m = read();
int w = 0;
for (int i = 1; i <= n; i++)
scanf("%s", s[i] + 1);
if (!bfs()) {
puts("J");
continue;
}
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
if (s[i][j] == 'W')
w++;
if ((w - dis[n][m]) & 1)
puts("I");
else
puts("J");
}
return 0;
}