[BZOJ1188/Luogu3185][HNOI2007]分裂游戏

题目链接:

BZOJ1188

Luogu3185

博弈论。

首先,每一堆石子都是互相独立,不影响的,那么就只需求解每一堆的\(SG\)函数\(Xor\)即可。

再想,对于每一堆石子,里面的每一个石头都是互相独立的,那么就只需求解一个石子的\(SG\)函数,再用\(p_i\)\(Xor\)起来就得到了答案。

那么如果是奇数不变,偶数个则为\(0\)

对于一个石子的\(SG\)函数暴力求即可。

妙啊喵啊

时间复杂度 \(O(Tn^3)\)

#include <cstdio>
#include <cstring>

int t,n,p[25],SG[25];
bool Bus[505];

int main()
{
    for(scanf("%d",&t);t--;)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;++i)scanf("%d",&p[i]);//这里用1~n编号
        for(int i=n;i>=1;--i)
        {
            memset(Bus,0,sizeof Bus);
            for(int j=i+1;j<=n;++j)
                for(int k=j;k<=n;++k)
                    Bus[SG[j]^SG[k]]=true;//后继状态mex
            for(int j=0;j<=500;++j)
                if(!Bus[j])
                    SG[i]=j,j=500;
        }
        int TSG=0,p1=0,p2=0,p3=0,Cnt=0;
        for(int i=1;i<=n;++i)
            if(p[i]&1)
                TSG^=SG[i];//是奇数,只需xor一次
        if(TSG)
            for(int i=1;i<n;++i)
                for(int j=i+1;j<=n;++j)
                    for(int k=j;k<=n;++k)
                        if(!(TSG^SG[i]^SG[j]^SG[k]))//能使Xor和变为0(必败)
                        {
                            ++Cnt;
                            if(!p1)p1=i,p2=j,p3=k;
                        }
        printf("%d %d %d\n%d\n",p1-1,p2-1,p3-1,Cnt);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/LanrTabe/p/10202994.html