CF 1383B GameGame

传送门

题目:给定长度为n的数组a,A和B轮流拿走一个数,开始时A和B拥有的v为0,A和B每次拿走一个数时,他的v = v^ ai,A和B都很聪明,问都按照最优的情况考虑,拿完所有数之后A和B的v的大小。

思路:我们可以想到二进制的高低位性质,所以一个人如果有一个最高位二进制为1而另外一个人是0,则前者一定赢。我们可以把所有数的二进制位取下来,我们知如果该二进制位为偶数,说明这个位一定可以变成0;否则如果为奇数,则一定会出现一个人是1,另一个是0的情况。根据枚举一些样例,可以总结出以下的规律:

(前提:该bit为奇数)

① cnt[bit] % 4 == 1  则前者一定赢,只要前者把这个1拿走

② cnt[bit] % 4 == 3 (*)  如果 (n - cnt[bit])% 2 == 0(&),则后者赢,因为后者一定可以让前者取到(*)多出的1,反之如果为1,则前者把(&)1拿走,让后者拿(*)多出的1

 

 1 #include<iostream>
 2 #include<string>
 3 #include<vector>
 4 #include<cstdio>
 5 
 6 #define ll long long
 7 #define pb push_back
 8 
 9 using namespace std;
10 
11 const int N = 1e5;
12 int bit[N];
13 
14 void solve()
15 {
16     int T;
17     cin >> T;
18     while(T--){
19         int n;
20         cin >> n;
21         
22         for(int i = 0; i <= 40; ++i) bit[i] = 0;
23 
24         for(int i = 1; i <= n; ++i){
25             int x, b;
26             cin >> x;
27             b = 0;
28             while(1){
29                 if(!x) break;
30                 bit[b++] += (x & 1);
31                 x >>= 1;
32             }
33         }
34 
35         int inx = -1;
36         for(int i = 40; i >= 0; --i){
37             if(bit[i] % 2 == 0) continue;
38             inx = i;
39             break;
40         }
41 
42         if(inx == -1){
43             cout << "DRAW" << endl;
44             continue;
45         }
46 
47         int a = bit[inx] % 4;
48         int b = (n - a) % 2;
49 
50         if(a == 3 && b == 0) cout << "LOSE" << endl;
51         else cout << "WIN" << endl;
52     }
53 
54 }
55 
56 int main() {
57 
58     ios::sync_with_stdio(false);
59     cin.tie(0);
60     cout.tie(0);
61     solve();
62     //cout << "ok" << endl;
63     return 0;
64 }

 

posted @ 2020-08-14 18:35  SummerMingQAQ  阅读(266)  评论(0编辑  收藏  举报