Being a Good Boy in Spring Festival(nim博弈的取胜方式数)一些超详细的推导

m堆牌,每次只能选择一堆牌抽取任意张(所以sg(n)=n)。

用s储存所有sg函数的异或值。根据题意可以知道是如果选择a【i】(第i堆,牌数为a【i】)最多可以抽a[i]张(废话),怎么样可以取胜呢——令抽取了x张牌后的nim和等于0。也就是说,s^a[i]^(a[i]-x)==0; (s^a[i]等于除了a[i]之外所以数的异或值)又因为一个数和它本身求异或值的话也就等于0,所以可以得出s^a[i]==a[i]-x (抽任意张牌,x肯定大于0),又因为x到底是几我们不确定,但是肯定大于零,所以可以把判断条件写为(a[i]>(s^a[i])),又因为运算符的优先级,所以要加括号。然后就是计数p++

#include<iostream>
#include<cstring>
using namespace std;
int  m, p,s; 
int a[101];

int main() {
	while (cin >> m) {
		if ( m == 0)break;
		s = 0;
		for(int i = 1; i <= m;i++) {
			cin >>a[i];
			s = s^a[i];//异或的和
		}
		for (int i = 1; i <= m; i++) {
			if (a[i] > (s ^ a[i]))p++;
		}
		if (s==0)cout << 0<< endl;
		else cout <<p << endl;
	}

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值