感觉还是很考验思维的…
部分思路来自茄子大大!!
记录一下有多少数包含第x位二进制,记作two[x]
若two[x]为偶数,那么不管怎么选,要么两个数最后这位都是偶数,要么都是奇数,不用管
所以找到最高位的num使得two[num]%2==1
最后选的数一定是在这一位分出胜负
那么现在的情况就是,谁能保证这一位拿到奇数个1,谁就赢
Ⅰ.当(two[num]−1)/2是偶数
先手必胜,因为先手可以先拿一个1
然后剩下(two[num]−1)/2次等后手拿了1,我再去拿1
这样由于(two[num]−1)/2是偶数,所以先手拿到奇数个1,必胜
扫描二维码关注公众号,回复:
11499954 查看本文章
Ⅱ.当(two[num]−1)/2是奇数
若n也是奇数,那么现在有奇数个位置(two[num])含1,偶数个位置不含1
那么后手一直跟着先手选,先手拿1后手才去拿1
先手拿(two[num]−1)/2次1,后手拿(two[num]−1)/2+1个1
后手必胜。
注意到这里没有考虑偶数个不含1的位置,因为只有当先手选不含1的位置后手才选。又因为是偶数个位置不含1,所以相当于没有影响
若n是偶数呢?
那么现在有奇数个位置(two[num])含1,奇数个位置不含1
现在不含1的位置有奇数个了,不能像前面一样不管了
但是先手可以先拿掉一个不含1的位置
现在变成有奇数个位置(two[num])含1,偶数个位置不含1
后n是奇数的情况一样了,只不过现在的先手相当于前面的后手,所以先手必胜
/*找到最大的id,使得有奇数个数包含这一位 */
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int a[maxn],two[32],t,n;
int main()
{
cin >> t;
while( t-- )
{
memset(two,0,sizeof(two));
cin >> n;
for(int i=1;i<=n;i++)
{
cin >> a[i];
for(int j=0;j<=30;j++)
if( (1<<j)&a[i] ) two[j]++;
}
int num=-1;
for(int i=0;i<=30;i++)//找最高位的奇数1
if( two[i]%2==1 ) num=i;
if( num==-1 ) cout << "DRAW\n" ;
else
{
if( (two[num]-1)/2%2==0 ) cout << "WIN\n" ;
else if( (two[num]-1)/2%2==1&&n%2==1 ) cout << "LOSE\n" ;
else cout << "WIN\n" ;
}
}
}