HDU-2509-Be the Winner | HDU-1907-John (反尼姆博弈)

HDU1907
HDU2509
题意:n堆物品,两人轮流拿,每次再一堆中最少拿一个,最多拿完,拿完的获胜,问谁获胜。
分析:反尼姆博弈的先手必胜态:
1.每堆都只有一个,只有偶数堆(尼姆和为0);
2.存在物品个数大于一个的堆,并且尼姆和不为0.

第一种情况好理解;
第二种情况当前尼姆和不为0,一定有一种拿法使得尼姆和为0,并且尼姆和为0的时候没有拿法使尼姆和还是0(证明见链接中取火柴的游戏),也就是说先后手面临的情况是这样的:
先手非0->后手0->先手非0->后手0->…直到只剩下一个物品数大于1的堆,这时先手将该堆剩下1个转化成自己必胜的情况(可以控制剩下一个或者零个使对方必败)。

2509规则稍有不同,能够拿中间的几个使某堆拿完后变成两堆,如@@@,拿走中间的一个,成为@   @,但是这样也不能拿一次使尼姆和为0的状态还是保持尼姆和为0,(看完上面情况的证明就明白了)
2509的AC代码:

#include<cstdio>
using namespace std;

int main()
{
    int n, nim, a[105];
    bool flag;
    while(~scanf("%d", &n))
    {
        flag = 0;
        nim = 0;
        for(int i = 0; i < n; i++)
        {
            scanf("%d", &a[i]);
            if(a[i] != 1)
            {
                flag = 1;
            }
            nim ^= a[i];
        }
        if(flag)
        {
            if(nim == 0)
                printf("No\n");
            else
                printf("Yes\n");
        }
        else
        {
            if(nim == 0)
                printf("Yes\n");
            else
                printf("No\n");
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值