jzoj4381. 【GDOI2016模拟3.11】游戏

题目描述

这里写图片描述

20~30%

直接暴力,前几个点可以过

另10%

因为N=1,所以直接判断M输出

100%

因为所有操作都是斜向的,所以可以把格子黑白染色,分成两个独立的游戏,于是可以博弈

每次考虑其中的一个矩阵的SG,选取其中的一个点看作其的一种情况。
显然每种情况都是一个局面,而这个局面的SG就是所有子游戏SG的异或和。
这里写图片描述

所以分LRX三种情况讨论,最后取mex

code

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define max(a,b) (a>b?a:b)
#define min(a,b) (a<b?a:b)
using namespace std;

struct A{
    int s,x1,y1,x2,y2;
} d[160001];
char a[21][21];
char b[21][21];
char c[21][21];
bool bz[21][21][21][21];
bool Bz[21][21][21][21];
int sg[21][21][21][21];
int Sg[21][21][21][21];
bool sg2[401];
bool Sg2[401];
int n,m,i,j,k,l,N,I,X1,Y1,X2,Y2,s;

bool cmp(A a,A b)
{
    return a.s<b.s;
}

int main()
{
    while (scanf("%d%d",&n,&m)!=EOF)
    {
        memset(a,' ',sizeof(a));
        memset(b,' ',sizeof(b));
        memset(c,' ',sizeof(c));
        memset(bz,0,sizeof(bz));
        memset(Bz,0,sizeof(Bz));
        memset(sg,0,sizeof(sg));
        memset(Sg,0,sizeof(Sg));

        N=max(n,m);

        fo(i,1,n)
        {
            scanf("\n");
            fo(j,1,m)
            scanf("%c",&a[i][j]);
        }

        fo(i,1,N)
        {
            fo(j,1,N)
            {
                if ((i+j)&1)
                b[(i-j+1)/2-(2-N)/2+1][(i+j+1)/2]=a[i][j];
                else
                c[(i-j)/2-(1-N)/2+1][(i+j)/2]=a[i][j];
            }
        }

        I=0;
        fo(i,1,N)
        {
            fo(j,1,N)
            {
                fo(k,i,N)
                {
                    fo(l,j,N)
                    {
                        I++;
                        d[I].s=(k-i+1)*(l-j+1);
                        d[I].x1=i;
                        d[I].y1=j;
                        d[I].x2=k;
                        d[I].y2=l;

                        if (i==k && j==l)
                        {
                            if (b[i][j]=='R' || b[i][j]=='L' || b[i][j]=='X')
                            {
                                bz[i][j][k][l]=1;
                                sg[i][j][k][l]=1;
                            }
                            if (c[i][j]=='R' || c[i][j]=='L' || c[i][j]=='X')
                            {
                                Bz[i][j][k][l]=1;
                                Sg[i][j][k][l]=1;
                            }
                        }
                    }
                }
            }
        }
        sort(d+1,d+I+1,cmp);

        j=1;
        while (j<=I && d[j].s==1)
        j++;

        fo(i,j,I)
        {
            memset(sg2,0,sizeof(sg2));
            memset(Sg2,0,sizeof(Sg2));

            X1=d[i].x1;
            Y1=d[i].y1;
            X2=d[i].x2;
            Y2=d[i].y2;

            if (X1==X2)
            {
                bz[X1][Y1][X2][Y2]=bz[X1][Y1][X2][Y1]|bz[X1][Y1+1][X2][Y2];
                Bz[X1][Y1][X2][Y2]=Bz[X1][Y1][X2][Y1]|Bz[X1][Y1+1][X2][Y2];
            }
            else
            {
                bz[X1][Y1][X2][Y2]=bz[X1][Y1][X1][Y2]|bz[X1+1][Y1][X2][Y2];
                Bz[X1][Y1][X2][Y2]=Bz[X1][Y1][X1][Y2]|Bz[X1+1][Y1][X2][Y2];
            }

            fo(j,X1,X2)
            {
                fo(k,Y1,Y2)
                {
                    s=0;
                    switch (b[j][k])
                    {
                        case 'L':
                            {
                                if (X1<j && bz[X1][Y1][j-1][Y2])
                                s^=sg[X1][Y1][j-1][Y2];
                                if (j<X2 && bz[j+1][Y1][X2][Y2])
                                s^=sg[j+1][Y1][X2][Y2];

                                break;
                            }
                        case 'R':
                            {
                                if (Y1<k && bz[X1][Y1][X2][k-1])
                                s^=sg[X1][Y1][X2][k-1];
                                if (k<Y2 && bz[X1][k+1][X2][Y2])
                                s^=sg[X1][k+1][X2][Y2];

                                break;
                            }
                        case 'X':
                            {
                                if (X1<j && Y1<k && bz[X1][Y1][j-1][k-1])
                                s^=sg[X1][Y1][j-1][k-1];
                                if (X1<j && k<Y2 && bz[X1][k+1][j-1][Y2])
                                s^=sg[X1][k+1][j-1][Y2];
                                if (j<X2 && Y1<k && bz[j+1][Y1][X2][k-1])
                                s^=sg[j+1][Y1][X2][k-1];
                                if (j<X2 && k<Y2 && bz[j+1][k+1][X2][Y2])
                                s^=sg[j+1][k+1][X2][Y2];

                                break;
                            }
                    }
                    if (b[j][k]=='L' || b[j][k]=='R' || b[j][k]=='X')
                    sg2[s]=1;

                    s=0;
                    switch (c[j][k])
                    {
                        case 'L':
                            {
                                if (X1<j && Bz[X1][Y1][j-1][Y2])
                                s^=Sg[X1][Y1][j-1][Y2];
                                if (j<X2 && Bz[j+1][Y1][X2][Y2])
                                s^=Sg[j+1][Y1][X2][Y2];

                                break;
                            }
                        case 'R':
                            {
                                if (Y1<k && Bz[X1][Y1][X2][k-1])
                                s^=Sg[X1][Y1][X2][k-1];
                                if (k<Y2 && Bz[X1][k+1][X2][Y2])
                                s^=Sg[X1][k+1][X2][Y2];

                                break;
                            }
                        case 'X':
                            {
                                if (X1<j && Y1<k && Bz[X1][Y1][j-1][k-1])
                                s^=Sg[X1][Y1][j-1][k-1];
                                if (X1<j && k<Y2 && Bz[X1][k+1][j-1][Y2])
                                s^=Sg[X1][k+1][j-1][Y2];
                                if (j<X2 && Y1<k && Bz[j+1][Y1][X2][k-1])
                                s^=Sg[j+1][Y1][X2][k-1];
                                if (j<X2 && k<Y2 && Bz[j+1][k+1][X2][Y2])
                                s^=Sg[j+1][k+1][X2][Y2];

                                break;
                            }
                    }
                    if (c[j][k]=='L' || c[j][k]=='R' || c[j][k]=='X')
                    Sg2[s]=1;
                }
            }

            j=0;
            while (sg2[j]) j++;
            sg[X1][Y1][X2][Y2]=j;

            j=0;
            while (Sg2[j]) j++;
            Sg[X1][Y1][X2][Y2]=j;
        }

        if (sg[1][1][N][N]^Sg[1][1][N][N])
        printf("WIN\n");
        else
        printf("LOSE\n");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值