hdu 2176 取(m堆)石子游戏 (裸Nim)

题意:

m堆石头,每堆石头个数:a[1]....a[m]。

每次只能在一堆里取,至少取一个。

最后没石子取者负。

先取者负输出NO,先取胜胜输出YES,然后输出先取者第1次取子的所有方法。如果从有a个石子的堆中取若干个后剩下b个后会胜就输出a b

 

思路:

裸的NIM。

单看一堆石子,没有石头sg[0]=0,一个石头sg[1]=1,....n个石头sg[n]=n。

故SG[a[1],a[2]...a[m]] = sg[a[1]]^...^sg[a[m]] = a[1]^...^a[m]

SG=0 为先手必败点。

 

代码:

///Nim游戏

int m,ans;
int a[200005];

int main(){
    while(scanf("%d",&m),m){
        scanf("%d",&a[1]);
        ans=a[1];
        rep(i,2,m){
            scanf("%d",&a[i]);
            ans=ans^a[i];
        }
        if(!ans)
            puts("No");
        else{
            puts("Yes");
            rep(i,1,m){
                if((ans^a[i])<=a[i]){
                    printf("%d %d\n",a[i],ans^a[i]);
                }
            }
        }
    }
}

 

posted @ 2014-10-01 21:05  fish7  阅读(193)  评论(0编辑  收藏  举报