题意:Koa the Koala和她的好朋友一起去玩游戏。这个游戏由n个非负的整数组成,Koa还有她的好友轮流玩这个游戏并且每个人都有一个初始分数0。让我们描述这个操作的每一步:
1.选择一个数字并且异或到自己的分数上。
如果两个人最后得到的分数一样,那么就是平局,否则分值最大的胜利。Koa先手。
分析:异或题,我们一般都从最高位开始考虑,异或具有一些性质,比如(1 oplus 1 = 0, 1 oplus 0 = 1, x oplus x = 0, x oplus 0 = x)。我们考虑所有的数,并从最高位开始考虑,,我们的koa是先手的,如果每个人都采用最优策略,那么第一个人拿什么,第二个人也会做同的操作,如果是这样的话,统计每个数最高位的1的个数和0的个数,如果有偶数个1的话,这些1异或起来就会为0,这两个人在这一位就会是平手,继续考虑下一位,直到出现奇数个1的时候,我们再分类讨论。
1.首先是平局的情况,那么所有数异或起来为0,即每一位都是平局,输出"DRAW"即可。
2.其次是如果出现某一位有奇数个1的话,我们分类讨论,首先是如果这一位1的个数%4 == 3并且0的个数%2 == 0,那么是后手赢,否则是先手赢。假设1的个数为x,0的个数为y。我们考虑x % 4的情况,如果x % 4 == 1的话,我们先手拿掉一个1,接下来另一个人做什么,我们都做相同的动作,如果y % 2 == 0的话,那很好说,最后我们的先手会多出一个1,如果y % 2 == 1的话,我们最后剩下的0,不管谁拿,都没事,因为还是先手赢,因为1的个数为4的倍数,我们只要和另一个人的动作相同即可。
考虑x % 4 == 3的情况,首先是y % 2 == 0,第一个人作什么,第二个人跟着照做,会发现不管怎么操作,第一个人会有偶数个1,那么就是第二个人赢。再考虑y % 2 == 1的情况,我们的第二个人拿走了一个0,那么就又变成了x % 4 == 3,并且y % 2 == 1的情况了,此是是第一个人胜利。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int N = 100005;
int a[N];
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int n;
scanf("%d", &n);
int res = 0;
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]), res ^= a[i];
if (res == 0)
{
puts("DRAW");
}
else
{
int s = 0, pos = 30;
for (int i = 31; i >= 0; --i)
{
if ((res >> i) & 1)
{
pos = i;
break;
}
}
int cnt = 0;
for (int i = 1; i <= n; ++i)
{
if ((a[i] >> pos) & 1)
++cnt;
}
int x = cnt;
int y = n - x;
if (x % 4 == 3 && y % 2 == 0)
puts("LOSE");
else
puts("WIN");
}
}
return 0;
}