输入:
4
1 1
1 0
2 2 1
7 992438 1006399 781139 985280 4729 872779 563580
输出:
1
0
1
1
解题思路:
首先分析平局的时候,如果这个数组中所有的数字异或起来结果为0,那么两者手中的数字最终一定相等。
不是平局的时候:
首先统计出每一位上1出现的次数,然后从高位开始看,如果这一位上1出现的次数为偶数,那么不会对最后的结果产生影响。如果说这一位上1出现的次数为奇数,这时候要分情况进行讨论。
(1)、此时0的个数为偶数。首先先手先取一个该位为1的数字给自己异或上,然后后手开始取,然后后书取什么,先手也取什么,如果后手取的是0,先手也取0,对结果没有影响,如果后手取的是1,如果这个1是后手给自己异或上的,那么先手取一个1给后手异或上,使得后手这个位上始终为0,如果后手取一个1给先手 异或,那么先手取一个1给自己异或,消除影响,此时先手这个位上始终为1,故该状态下,先手必胜。
(2)、此时0的个数为奇数。此时我们应该意识到,这里无论怎么选因为1的个数是奇数,除非我们选择保留自己的1选个其他,否则都是必败。本质上说谁拥有最后一次选择1的权利,谁就赢了。正常来说,1的数量是奇数个,双方都抢1的话,最后赢的一定是先手,所以如果后手想要获胜,那么就要靠抢0来改变最终抢1的奇偶性,此时先手必败。
上代码:
#include <bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int t,n;
int num[30];
void getcnt(int x)
{
int cnt=0;
while(x)
{
cnt++;
int temp=x&1;
if(temp)
num[cnt]++;
x>>=1;
}
}
int main()
{
cin>>t;
while(t--)
{
memset(num,0,sizeof num);
cin>>n;
int ans=0;
for(int i=1;i<=n;i++)
{
int x;
cin>>x;
getcnt(x);
ans=ans^x;
}
if(ans==0)
cout<<0<<endl;
else
{
for(int i=24;i>=1;i--)
if(num[i])
{
if(num[i]==1)
{
cout<<1<<endl;
break;
}
else
{
if(num[i]%2)
{
if(n%2)//0的个数为偶数个
{
cout<<1<<endl;
break;
}
else//0的个数为奇数个
{
cout<<"-1"<<endl;
break;
}
}
}
}
}
}
return 0;
}