hdu 5795 A Simple Nim (sg 博弈)

官方题解:

A Simple Nim

sg[0]=0

当x=8k+7时sg[x]=8k+8,

当x=8k+8时sg[x]=8k+7,

其余时候sg[x]=x;(k>=0)

打表找规律可得,数学归纳法可证。

具体的打表放在了代码里面 ,详见init函数

/*by*/
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long LL;
const LL N=1e6+10;
const LL mod=1000000007;
const LL INF=0x3f3f3f;
LL sg[300],vis[300];
void init()/*打表求前300的sg函数找规律*/
{
    int i,j,k;
    for(i=1; i<300; i++) {
        memset(vis,0,sizeof(vis));
        for(j=1; j<=i; j++) {
            for(k=1; j+k<=i; k++) {
                if((i-j-k)!=0) {
                    vis[sg[j]^sg[k]^sg[i-j-k]]=1;
                }
            }
        }
        for(j=0; j<i; j++)
            vis[sg[j]]=1;
        j=0;
        while(vis[j])
            j++;
        sg[i]=j;
    }
    for(i=0; i<30; i++)
        printf("sg[%d]=%lld
",i,sg[i]);
}
int main()
{
    //init();
    int T;
    cin>>T;
    while(T--) {
        int n,i;
        LL a[N],ans=0,tmp;
        scanf("%d",&n);
        /*ans进行结果的异或*/
        for(i=1; i<=n; i++) {
            scanf("%lld",a+i);
            tmp=a[i];
            if(a[i]%8==7)
                tmp++;
            else if(a[i]%8==0)
                tmp--;
            ans^=tmp;
        }
        if(!ans)
            printf("Second player wins.
");
        else
            printf("First player wins.
");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/yu0111/p/5742038.html