题意
传送门 Codeforces 138D
题解
发生分割的游戏,考虑 G r u n d y Grundy Grundy 值。与直接分割平面不同之处在于游戏场地是方格状的,考虑将平面上的格子沿主对角线交替染为黑(坐标和为奇数)、白色(坐标和为偶数),黑色与白色格子切割时是互不影响的。那么将游戏按黑白格子考虑两个独立的分割游戏,用 N i m Nim Nim 游戏的方法判断胜负。
为了方便处理,将矩形旋转 45 45 45 度,即同一条主对角线的点横坐标相同,同一条副对角线上的点纵坐标相同,然后将最小值设为零,即 ( x , y ) (x,y) (x,y) 映射为 ( x + y , y − x + M − 1 ) (x+y,y-x+M-1) (x+y,y−x+M−1)。此时考虑横纵向的分割即可。
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
using namespace std;
#define maxn 45
int N, M, mem[maxn][maxn][maxn][maxn][2];
char mp[maxn][maxn];
int gs(int x1, int x2, int y1, int y2, int f)
{
int &res = mem[x1][x2][y1][y2][f];
if (res != -1)
return res;
bool s[maxn] = {0};
for (int y = 0; y < N; ++y)
{
for (int x = 0; x < M; ++x)
{
int _x = x + y, _y = y - x + M - 1;
if ((_x & 1) == f)
{
if (x1 <= _x && _x < x2 && y1 <= _y && _y < y2)
{
int g;
char c = mp[y][x];
if (c == 'L')
g = gs(x1, _x, y1, y2, f) ^ gs(_x + 1, x2, y1, y2, f);
else if (c == 'R')
g = gs(x1, x2, y1, _y, f) ^ gs(x1, x2, _y + 1, y2, f);
else
g = gs(x1, _x, y1, _y, f) ^ gs(_x + 1, x2, y1, _y, f) ^ gs(x1, _x, _y + 1, y2, f) ^ gs(_x + 1, x2, _y + 1, y2, f);
s[g] = 1;
}
}
}
}
while (s[++res])
;
return res;
}
int main()
{
scanf("%d%d", &N, &M);
for (int i = 0; i < N; ++i)
scanf(" %s", mp + i);
memset(mem, -1, sizeof(mem));
puts(gs(0, N + M - 1, 0, N + M - 1, 0) ^ gs(0, N + M - 1, 0, N + M - 1, 1) ? "WIN" : "LOSE");
}