题意:给定 n 堆石子,每次可以进行如下一回合操作:
①选择一堆石子并取走部分石子,设这堆石子有 s 块,取走部分后剩下 k 块,需满足的条件是 k^s < s;
②新添加一堆大小为 k^s 的石子,而且整个游戏中两玩家各有一次机会把 (k^s) 替换成 ((2k)^s);
问先手是否必胜;
分析: 不管替换,先考虑只有一堆石子共 s 块,每次操作相当于把一堆 s 分成 k 和 k^s 两堆,我们知道当一堆石子的数量为 2^u 的形式时是不可再分的了(不可能满足条件①),那么最后我们会把这堆石子分成 m 堆,且每堆都满足 2^u 的形式,则共分了 m-1 次,若 m-1 为奇数则先手必败,为偶数则先手必胜;所以我们在意的是 m 堆的奇偶性,再回到操作①的约束下,k 和 k^s 的奇偶性和 是等于 s 的奇偶性的(稍微理解一下异或),所以奇偶性永远不会改变,则我们可以计算 s 的二进制 1 的奇偶性来判断,而对于替换操作,((2k)^s)与(k^s) 的奇偶性也是一致的,所以根本不用管;
所以对于 n 堆石子,对每一堆数量二进制 1 的个数为偶数的数量做异或和;
代码:
#include<cstdio>
#include<iostream>
using namespace std;
int bitcount(int x){
int ans=0;
while(x){
x=x&(x-1);
ans++;
}
return ans;
}
int main()
{
int q;
scanf("%d",&q);
for(int cas=1;cas<=q;cas++){
int res=0;
int n;
scanf("%d",&n);
while(n--){
int x;scanf("%d",&x);
res^=(bitcount(x)%2==0);
}
printf("Case %d: ",cas);
if(res) puts("Yes");
else puts("No");
}
}
来源:CSDN
作者:伴君
链接:https://blog.csdn.net/weixin_43209425/article/details/104650760