hdu 4388 Stone Game II 博弈 库函数查找x数字二进制为1的个数

本文解析HDU4388题目,涉及博弈论中的石子游戏策略。通过分析石子堆数量与二进制位的关系,得出先手玩家获胜条件。代码示例使用C++实现,利用__builtin_popcount函数计算二进制中1的个数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:hdu 4388

参考博客:https://blog.youkuaiyun.com/y1196645376/article/details/52143551

题意:

最初有n堆石子,每堆石子个数已知。两人轮流执行操作,如果当某人无法执行有效操作时即输。

操作分两步:

    第一步为:选择其中一堆石子假定石子个数为a,拿走个数不为0的一些石子使得该堆石子剩余k个并且保证(0 < k < a,k^a < a),^为异或符号。

    第二步为:加入一堆新的石子,石子个数为k^a,当然你也可以使用技能使得加入的石子个数变为(2k)^a。不过每个人每局游戏只能使用一次技能。

无法执行有效操作即第一步或者第二步无法执行时。

 

题解:直接看代码,里面有很详细的注释。

///先看下题目要求,每次留下的k,满足 0<k<n && kXORn <n,
///这说明,k只能在n中取二进制位1的数位,例如n=5(101),那么k只能是4(100)或者1(001)
///还能知道堆数为2^i时(二进制只有一位1),不能再分了,已到达边界了。
///然后我们假设先考虑一堆石子(n=1),k为这堆石子二进制位为1的个数,假设为偶数,先手win,也就是n+k为奇数时,先手win
///接着我们考虑有多堆石子(n>1),sum为这堆石子二进制1的个数,类比于一堆石子,sum+n为奇数时先手win,多堆可以看做单堆单堆的取,
///对了,每位选手还有一次技能加成的机会,我们要清楚的一点的是,这次加成的是用在新加堆上的,并且也不会改变新加堆的二进制位为1的个数
///例如n=13(1101),留k=5(101),2*k=1010, k XOR n=1000 ,2*k XOR n=0111,可见,不管用不用技能,新加堆的二进制位为1的个数的奇偶数还是没变。over。

/*
例如
n=15(1111)

1 111 先手
1 100 11 后手
1 100 1 1 先手

*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>


using namespace std;

int main()
{

    int ncase;
    scanf("%d",&ncase);

    for(int T=1;T<=ncase;T++)
    {
        int n;
        scanf("%d",&n);

        int x,sum=0;

        for(int i=1;i<=n;i++)
        {
            scanf("%d",&x);
            sum+=__builtin_popcount(x); ///库函数查找x数字二进制为1的个数,
            ///这库函数有个小坑,前面的下横线要两条,艹。
        }

        if((sum+n)&1) printf("Case %d: Yes\n",T);
        else printf("Case %d: No\n",T);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值