Bit Operations and Binary

foreword

It mainly records some operations using binary, which is convenient for efficient problem solving.

Basic operations and rules

Let's first talk about the basic operation rules of this bit operation and the basic rules that can be used to solve problems.

& operation

1&1=1

1&0=0

0&0=0

^ operation

1^1=0

1^0=1

0^0=0

| operation

1|1=1

1|0=0

0|0=0

left and right shift operation

a<<1: a is shifted left by one

a>>1: a is shifted to the right by one

basic law

1. When a computer performs operations, it is essentially performing binary operations, which means that we can make full use of this property to achieve unexpected results.

2. The sum of K numbers in K base without carry is 0

3. A binary bit is XORed with 1 to save the current state

4. Subtraction of binary numbers will convert the lowest 1 to 0

If this is combined with our Law 1, many very interesting operations will occur.
Then I will introduce some usages in order.

case

^ Computing tricks

Give a requirement, for example an array [1,1,2,2,3,3,4,5,5]

Except for a certain number, all other numbers appear in pairs, and now let you find the number that does not appear in pairs, such as 4 in the example.

Scheme 1 hash method

First of all, it is easy to think of the hash method, but in this case, the space complexity is obviously not good, and it is necessary to traverse the hash array once to know the answer.

public class 位运算1 {
    
    

    public static void main(String[] args) {
    
    

        int[] a = new int[]{
    
    1,1,2,2,3,3,4,5,5};

        int[] hash = new int[a.length];

        for (int j : a) {
    
    
            hash[j]++;
        }

        for (int i = 0; i < hash.length; i++) {
    
    
            if(hash[i]==1){
    
    
                System.out.println(i);
            }
        }

    }

}

Scenario 2 ^ Operation

The time and space of the solution is not good, so if you want to solve this solution, you need to use the ^ operation.

Since: 1^1=0 0^0=0

So when 3 and 3 are XORed, the result must be 0, so the paired XORs are all 0, then 0 and 4 XORs are naturally 4

public class 位运算1 {
    
    

    public static void main(String[] args) {
    
    
        //找出不同
        int[] a = new int[]{
    
    1,1,2,2,3,3,4,5,5};

          int x = 0;
          for (int i : a) {
    
    
              x = x^i;
          }
          System.out.println(x);
    }

}

Count the number of bits that are 1

Given a decimal number, ask you to see how many 1s are in the digits of the decimal number

For example, 3–>011
has two here

Since there are many solutions here, I will talk about them together here.

The easiest way to deal with

Similarly, it is easy to think of directly converting this decimal to binary and then counting 1.

public class 运算二 {
    
    
    public static void main(String[] args) {
    
    
        int a = 3;
        char[] chars = Integer.toString(a, 2).toCharArray();
        int count = 0;
        for (char aChar : chars) {
    
    
            if(aChar=='1'){
    
    
                count++;
            }
        }
        System.out.println(count);
    }
}

This is one of the easiest options to think of. So here, you can actually use bit operations to do it quickly.

use shift operation

image.png

The way of thinking is like this, and it's easy to write.

public class 运算二 {
    
    
    public static void main(String[] args) {
    
    
        int a = 3;
        int count = 0;
        for (int i = 0;i<32;i++){
    
    
            //4个字节32位
            if((a&(1<<i)) == (1<<i)){
    
    
                count++;
            }
        }
        System.out.println(count);
    }
}

Of course, the left shift is used here, and it is ok for us to shift a to the right.

Subtract 1 Magical Uses

Remember point 3 I wrote earlier.
if a number such as a=3

image.png

public class 运算二 {
    
    
    public static void main(String[] args) {
    
    
        int a = 3;
        int count = 0;
        while (a!=0){
    
    
            a = a&(a-1);
            count++;
        }
        System.out.println(count);
    }
}

| Operation state transition

Remember this, our previous topic?

State compression + dynamic programming (Blue Bridge Cup 2019 java group A candy problem)

There is a very clever thing in it, which is to convert the following single primitive group into a state number, which is convenient for dp

6 5 3  
1 1 2  
1 2 3  
1 1 3  
2 3 5  
5 4 2  
5 1 2  
6 5 3    状态压缩
		二进制  十进制
1 1 2   00011	3
1 2 3	00111	7
1 1 3	00101	5

Our code works like this

w[i] |=(1<<k-1) ;

This w is to save our state.
At that time, the meaning of dp is how many candies are needed in the current state.

Here is a little bit about the construction of the dp array, you just need to remember that the value of this dp will always be saved, the current optimal solution, such as this candy problem, requires the minimum number of packets, first see the smallest and largest words, it must be It is dp or greedy, but everyone who understands greed understands, directly consider dp (nothing more than 0-1 knapsack problem or multiple knapsacks, etc.) to require this number of packages, then it must be dp[i] = value The value must be the number of packages, then What this i is, then it must be a variable that determines or affects value. So if we don't know how to save the state here, then the dp we finally build is very likely to be like this dp[][][]...=value The number of [] depends on how many candies you have.

So how this is transformed, I didn't make it clear before, so I'll say it again here.
In fact, it is very simple. What we want to do in the end is
the binary form of the format 0 0 0 0 0 (of course, it will be converted to decimal for the computer at the end, so that we directly use a number to represent a state)

We first see the set of data
1 1 2

0 0 0 0 0 initial state
After that, we take the E, shift 1-1 bits to the left, and then do
the OR operation, so we get
0 0 0 0 1

Another 1
or
0 0 0 0 1
is followed by 2 Left shift 2-1 units and then bitwise operation

0 0 0 1 1

So 3 represents the state of 1 1 2.

So bit operations are still very clever.
If I want to play the Blue Bridge Cup, I think it is still very likely to play this type of state compression. The state is compressed and then put on a backpack.

Regarding the backpack problem, I am also in the process of summarizing, because there are many problems, the first is the search problem, basically we directly DFS, BFS don't think about anything else, at most think about two points. If it is a dp problem, what is the most valuable problem, basically dp, and then there are variants of these dp problems that are basically the knapsack problem. The most I have seen so far is nothing more than a complete knapsack, a 0-1 knapsack, and then we set it up again Model, and then do space optimization, basically that's it. How about the rest? It depends on the actual situation. Of course, there are still some mathematical problems. After all, the Blue Bridge Cup is an algorithm competition. There will still be some mathematical problems. You must master some mathematics. Theory, but basically I will give up when I see it, unless it can be violent and exhaustive (that is, backtracking) (so master the three major points, recursive backtracking, search (DFS, BFS, bisection), dp (eight backpack problems)) and then Brush to the death, of course, this is just my current idea. If there is a big boss, please give me some advice (comment area)
To be honest, I am not a professional contestant.

Guess you like

Origin blog.csdn.net/FUTEROX/article/details/123482918