传送门:http://codeforces.com/problemset/problem/168/d
思路:这题比较恶心,细节很多,不过还好cf可以看数据...
首先考虑一个弱化版,只会横着或竖着以及横着和竖着一起来。
我们可以发现,一次操作后就相当于把一个大的游戏分成1或2或4个独立小游戏
SG值与位置也有关系,所以SG[u][d][l][r]表示左上坐标为(u,d)右下坐标为(l,r)的SG值
然后对于斜着的,我们考虑把它旋转45度,但是这有一个问题,一次操作并不能分出几个独立的小游戏(画图就可以发现了)
于是考虑把棋盘黑白染色,这样就可以分出独立的游戏了。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int sg[25][25][25][25],b[25][25],n,N,M;char a[25][25];bool bo[1010];
int work(int u,int d,int l,int r){
if (u>d||l>r) return 0;
if (sg[u][d][l][r]!=-1) return sg[u][d][l][r];
for (int i=u;i<=d;i++)
for (int j=l;j<=r;j++)
if (b[i][j]==1) work(u,i-1,l,r),work(i+1,d,l,r);
else if (b[i][j]==2) work(u,d,l,j-1),work(u,d,j+1,r);
else if (b[i][j]==3) work(u,i-1,l,j-1),work(u,i-1,j+1,r),work(i+1,d,l,j-1),work(i+1,d,j+1,r);
memset(bo,0,sizeof(bo));
for (int i=u;i<=d;i++)
for (int j=l;j<=r;j++)
if (b[i][j]==1) bo[work(u,i-1,l,r)^work(i+1,d,l,r)]=1;
else if (b[i][j]==2) bo[work(u,d,l,j-1)^work(u,d,j+1,r)]=1;
else if (b[i][j]==3) bo[work(u,i-1,l,j-1)^work(u,i-1,j+1,r)^work(i+1,d,l,j-1)^work(i+1,d,j+1,r)]=1;
for (int i=0;;i++) if (!bo[i]) return sg[u][d][l][r]=i;
}
int getans(int odd){
memset(sg,-1,sizeof(sg));
memset(b,0,sizeof(b));
for (int i=1;i<=N;i++)
for (int j=1;j<=M;j++)
if (((i+j)&1)==odd)
b[(i+j)>>1][(j-i+N+1)>>1]=a[i][j]=='L'?1:a[i][j]=='R'?2:3;
/*for (int i=1;i<=n;i++,puts(""))
for (int j=1;j<=n;j++)
printf("%c",b[i][j]==1?'L':b[i][j]==2?'R':b[i][j]==3?'X':'0');
puts("");*/
return work(1,n,1,n);
}
int main(){
while (scanf("%d%d",&N,&M)!=EOF){
n=(N+M)>>1;
for (int i=1;i<=N;i++) scanf("%s",a[i]+1);
puts(getans(0)^getans(1)?"WIN":"LOSE");
}
return 0;
}