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

博弈论与SG函数实战

题目链接:

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;
}

转载于:https://www.cnblogs.com/LanrTabe/p/10202994.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值