The 12th Blue Bridge Cup Java Provincial Competition Group A Questions: XOR Sequence

[Title description]
Initially, Alice and Bob have integers a and b, respectively, and a given sequence of length n. The initial values ​​of a and b are both 0. Alice and Bob take turns to operate, Alice starts first, and each step can choose one of two options:
Option 1: choose an X from the sequence; XOR the number to Alice.
Option 2: Pick an X from the sequence; XOR Bob's numbers.
Each number Xi can only be used once. When each number is used once, the game is over. The side with the highest number wins, and the two sides have the same number, which means a draw.
Both sides are smart enough to adopt the optimal strategy and ask who will win?

[Input format]
Each evaluation case contains multiple sets of queries. The queries are independent of each other.
The first line of input contains an integer T, representing the number of queries.
Each of the next T lines contains a set of queries. The first integer n in the i-th row; represents the length of the sequence, and the following n integers X1, X2,...Xm represent each number in the sequence.

[Output format]
Output T lines, corresponding to the answers of each group of inquiries in turn.
Each line contains an integer 1, 0, or -1 to indicate that Alice wins, draws, or loses, respectively.

【Sample input】
4
1 1
1 0
2 2 1
7 992438 1006399 781139 985280 4729 872779 563580

【Sample output】
1
0
1
1

[Evaluation case scale and convention]
For all evaluation cases, 1 ≤ T ≤ 200000, 1 ≤ ∑Ti=1 ni ≤ 200000, 0 ≤ Xi < 220.


[Problem-solving ideas]
Reference: this blog

First of all, why is the ending of the game determined given a sequence of numbers?
A win means: A can adopt a certain strategy, no matter how B responds, A guarantees that he will win;
B wins means: B can adopt a certain strategy, no matter what A responds, B guarantees that he will be able to win. Win;
for XOR: 0^X - keep X; 1^X - flip X;
an even number of flips will go back to the original state, i.e. XOR with an even number of 1s will remain unchanged.

The last two result numbers A^B = a^b^sum, where sum is the XOR sum of all the numbers in the given sequence, sum = X1^X2^...Xni, so if it is a tie (ie A = B), then A^B=0 (ie sum = 0).

Now when sum != 0 is considered, because it is a bitwise XOR, and the size of the two values ​​of A and B is compared at the end, the comparison should start from the highest bit of the binary. If the highest bit is equal, compare the next highest bit, and then go down. , until the result can be judged.

An int array res[i] is used to represent the number of 1s in the i-th bit of binary. If res[i] of a certain bit is an odd number, that is, there are an odd number of 1s on the bit that are XORed with a and b. For example, there are 5 1s, because 0 does not change the state, the state transition process of its (a, b) must be: (0, 0) -> flip -> draw -> flip -> draw -> flip, that is to say in a draw On either (0, 0) or (1, 1) basis, whoever has the last flip (ie the last 1) between Alice and Bob wins the game!

So how do you let the last 1 turn on you? 0 is about to be used, because 0 does not change the size of the number, but it is equivalent to giving yourself a "bye". Or consider the situation of the above 5 1s: if an even number of 0s is inserted before the last flip (no matter where it is), the last flip right of 1 comes to the first hand Alice, and the first hand wins; if before the last flip (regardless of the position) In what position) insert an odd number of 0s, then the last flip right of 1 comes to the backhand Bob, and the backhand wins.

Because Alice and Bob are both "smart enough", in the face of an odd number of 1s, Bob must "snatch 0", so that he has a chance to survive, and Alice also has to "snatch 0" to deal with it, so that the last flip right returns In your own hands, because the number of 0s is limited, the final decision to win or lose is the parity of the 0s.

Therefore, if the res[i] of a digit is an even number, the digit of the game result must be equal, and the next digit is considered; if the number of 1s on the i-th digit is 1, it must be the first mover to win (output: "" 1"); if the number of 1's in the i-th position is an odd number greater than 1, and the number of 0's is an even number, the first hand wins (output: "1"); if the number of 1's in the i-th position is greater than 1 Odd number, if the number of 0 is odd, the second hand wins (output: "-1").


Java code:

import java.util.ArrayList;
import java.util.Scanner;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        //该ArrayList用来暂存每次询问结果,待最后一次询问结束再统一输出
        ArrayList<Integer> res = new ArrayList<>();
        //n次询问
        for (int i = 0; i < n; i++) {
    
    
            int[] weis = new int[24]; //该数组用于存储二进制形式下每一位1的数量
            int m = scanner.nextInt();
            //长度为m的数列转为二进制并处理
            for (int j = 0; j < m; j++) {
    
    
                long l = scanner.nextLong();
                String string = Long.toBinaryString(l); //转为二进制
                String reStr = new StringBuilder(string).reverse().toString(); //反转,即高低位反转,便于存储与后面处理
                //判断二进制形式下每一位是否为1
                for (int k = 0; k < reStr.length(); k++) {
    
    
                    if (reStr.charAt(k) == '1') weis[k]++;
                }
            }
            //对每次询问后每一位中1的个数判断从而得到结果,并将结果先暂时存储在ArrayList-res中
            for (int j = weis.length - 1; j >= 0; j--) {
    
    
                if (weis[j] % 2 == 0 && j == 0) {
    
    
                    res.add(0);
                    break;
                }else if (weis[j] % 2 == 0){
    
    
                    continue;
                }
                if (weis[j] == 1){
    
    
                    res.add(1);
                    break;
                }else if (weis[j] % 2 == 1 && (m - weis[j]) % 2 == 0){
    
    
                    res.add(1);
                    break;
                }else if (weis[j] % 2 == 1 && (m - weis[j]) % 2 == 1){
    
    
                    res.add(-1);
                    break;
                }
            }
        }
        //输出结果
        for (int x : res){
    
    
            System.out.println(x);
        }
    }
}

Guess you like

Origin blog.csdn.net/m0_46653805/article/details/123666722