尼姆博弈_poj2234+poj2975

尼姆博奕:有N堆物品,其中第i堆有Pi个物品,每次从一堆里选出若干物品去掉(不能不取出物品),两个人轮流取物,谁不能继续取谁就先输或者赢了。

题目1:有n堆火柴,每次可以从任意堆拿出任意数量的火柴,谁拿走最后的谁就赢。

题目分析:我们将n堆火柴数异或。若结果非0,则先走的玩家赢

#include <iostream>
using namespace std;
int main() {
    int n,ans,temp;
    while(scanf("%d",&n) != EOF)
    {
        scanf("%d",&ans);
        n--;
        while(n--)
        {
            scanf("%d",&temp);
            ans ^= temp;
        }
        if(ans)
            printf("Yes/n");
        else
            printf("No/n");

    }
    return 0;
}


题目2:有n堆石子,两人轮流从任一堆中取出任意个石子(至少一个),最后一个取石子的人为赢家。问最后有多少种赢法?

题目分析:首先求n堆石子数异或后的结果t,若t=0,则输;接着,设第i堆石子的数目为a[i],若t+a[i]<a[i]则输,因此我们要统计出有多少堆的石子数大于t+a[i]。

    #include<cstdio>  
    #include<cstring>  
    #include<iostream>  
    using namespace std;  
    const int maxn=1001;  
    int n,a[maxn];  //数组a存储每堆石子数,n是堆数
    int main()  
    {  
        while(scanf("%d",&n)&&n)  
        {  
        int t=0;  
        for(int i=0;i<n;i++)  
        {  
            scanf("%d",&a[i]);  
            t^=a[i];  
        }  
        int ans=0;  //统计赢得次数
        for(int i=0;i<n;i++)  
            if((t^a[i])<a[i])  
            ans++;  
        printf("%d\n",ans);  
        }  
        return 0;  
    }  




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值