文章标题

Being a Good Boy in Spring Festival

-

题目:

http://acm.hdu.edu.cn/showproblem.php?pid=1850

题意:

给定多堆的纸牌,每堆的纸牌数目也给定,游戏者可以从某一堆中取出任意多个数目的纸牌,请问先手如果能赢,他第一步取纸牌的可行的方案数?

类型:

博弈,nim博弈

思路:

运用尼姆博弈的方法求出所有堆纸牌数的异或之后的值t,然后判断是否为0,如果为0,先手必败,如果不为0,然后把先手第一步取纸牌的方案数,刚开始我认为把从每一堆的纸牌数枚举一遍,然后与t^a[i]再进行异或,若为0,则方案数加1。可是这样提交之后发现竟然TLE(超时),然后我就再次进行思考,发现(a[i]-x)^(t^a[i])==0时可行方案数加1,由观察可以知道x的值对于每一个a[i]要么唯一,要么不存在。所以可以发现:(a[i]-x)==(t^a[i])。又因为x唯一,所以有a[i]>t^a[i]时,必定存在并且只存在一个x使得先手可以得胜,因此,对于每一个a[i]就直接判断a[i]>t^a[i]就可以得到方案数是否加1。

代码:

#include<iostream>
#include<cstdio>
using namespace std;
long long  a[105];
int main()
{
int n;
while(scanf("%d",&n)&&n)
{
    long long  t=0;
    for(int i=0; i<n; i++)
    {
        scanf("%d",&a[i]);
        t^=a[i];
    }
    int counn=0;
    if(t==0)
        printf("0\n");
    else
    {
        for(int i=0; i<n; i++)
        {
            if((t^a[i])<a[i])
                counn++;
        }
        printf("%d\n",counn);
    }
}
return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值