题目:给定N个石子堆,两个人轮流取石子,每次只能取小于等于当前石子堆的石子数量,谁不能拿石子即输;
解:组合游戏,首先计算sg值观察规律,容易得出当N为偶数时sg(n)=n/2;当N为奇数时sg(n)=sg(n/2);
sg[0]=0;
for(int i=1;i<=20;i++)
{
memset(vis,0,sizeof(vis));
for(int j=1;j*2<=i;j++) vis[sg[i-j]]=1;
for(int j=0;;j++)
{
if(!vis[j])
{
sg[i]=j;
printf("%d\n",j);
break;
}
}
}
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
typedef long long LL;
LL sg(LL x)
{
return x%2==0?x/2:sg(x/2);
}
int main()
{
int t, n;
scanf("%d", &t);
while(t--)
{
int n;
scanf("%d", &n);
LL v=0;
for(int i=0;i<n;i++)
{
LL x;
scanf("%lld", &x);
v^=sg(x);
}
if(v) printf("YES\n");
else printf("NO\n");
}
return 0;
}