Daizhenyang's Coin HDU - 3537

原题链接
考察:博弈论
思路:
  这题不会只能说明对sg函数理解不够透彻了(比如我.
  明确sg函数是解决所有ICG游戏的通解,而本题很明显是ICG游戏(所有执行步骤与执行者无关).
  那么所有面朝上的硬币都可以视为一个起点.以下标为0的面朝上硬币为例,那么sg(0) = 1.由此也可以推到sg(1) = 2.我们可以由翻0~2枚左边硬币的步骤算出sg函数.打表sg函数值,可以发现3 5 6 8 10 12 15...的sg值都是2*i+1.这些数字有什么特点呢?根据猜测(看他人题解),都是二进制1的个数为偶数的数.
  坑点:去重,排序

Code:

#include <iostream> 
#include <cstring>
#include <set>
using namespace std;
const int N = 110;
int n,f[N];
set<int> s;
//int sg(int x)
//{
//	if(f[x]!=-1) return f[x];
//	set<int> s;
//	s.insert(0);//将x处的硬币翻转 
//	for(int i=0;i<x;i++)//翻两个 
//	  s.insert(sg(i));
//	for(int i=0;i<x;i++)
//	  for(int j=i+1;j<x;j++)
//	    s.insert(sg(i)^sg(j));
//	for(int i=0;;i++)
//	  if(!s.count(i)) return f[x] = i;
//}
int lowbit(int x)
{
	return x&-x;
}
int get(int x)
{
	int cnt = 0;
	for(int i=x;i;i-=lowbit(i)) cnt++;
	return cnt;
}
int main()
{
	while(scanf("%d",&n)!=EOF)
	{
		int x,res = 0;
                s.clear();
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&x);
			s.insert(x);
		}
		for(auto it:s)
		{
			int x = it;
			if(!x) res^=1;
			else if(get(x)&1) res^=2*x;
			else res^=2*x+1;
		}
		if(res) puts("No");
		else puts("Yes");
	}
	return 0;
}
posted @ 2021-05-24 21:43  acmloser  阅读(37)  评论(0编辑  收藏  举报