HDU - 4388 (Stone Game II)

题意:给定 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
#include
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");
	}
}

 

你可能感兴趣的:(博弈)