# preface

Give yourself: 26 days away from the Blue Bridge Cup. I've been preparing for a whole month and a half, and I haven't put too much pressure on myself. occasionally Play the piano and play the band, and occasionally play games, which is basically in the state of half learning and playing. The most important part of the previous Blue Bridge Cup The most basic problems have been basically done once (the slightly difficult ones have also been done a little bit, but the code is too stupid Dare to write in that note), a sentence often said when doing questions can basically express the experience after doing these questions: lying in the trough, It turned out to be so. How could I not have thought (how could I think so complicated) that now I finally started the programming problem In the Blue Bridge Cup, the programming questions are big, and some questions are scored according to efficiency, so all the next questions are made first To give priority to optimization and put it last, we should first do the most basic problems, and then gradually increase the difficulty. Finally, if the foundation is not strong, the earth will shake! --------------------------------------------------------------------------------------------------------- 2021.5.8 It's been two weeks since the end of the Blue Bridge Cup. I haven't touched the computer for two weeks hahahah，ginseng Plus JAVA C Group (the first game), took a provincial second, because it was the first time to participate in the game, although C Group 2 is rubbish, but it's OK for me. After all, looking back on today last year, I can't shit (2020).8 Barely until the end of the month Strong energy use C Write a in English for From 1+reach n，2020.2 Learn how to use it at the end of the month for if-else Because of the violence cup, Some basic algorithms are understood, but they are not used in the competition because they are not proficient or understood. The algorithm is really simple It is difficult, but what is valuable is often difficult. Therefore, the revolution has not yet succeeded, and comrades still need to work hard

# 1, Basic mathematics

## 1. Prime (prime)

Feature: can only be divided by 1 and itself

### I. judging prime

Title: enter a number to judge whether the number is a prime number

Idea:

import java.util.Math public class Main { public static void prime (int num) { if(num == 1 || num == 2) System.out.print("is Prime"); else if (num <= 0) System.out.print("Error"); else { for (int i = 2; i <= Math.sqrt(num);i ++) { if (num % i == 0) System.out.print("isn't Prime"); else System.out.print("is Prime"); } } } }

### II. Screening prime

Title: find all prime numbers in 2020

Idea:

## 2. Divisor (factor)

Features: the quotient of integer a divided by integer b(b ≠ 0) is exactly an integer without remainder. We say that b is the factor (divisor) of A.

### I. judgment factor

(the 11th Blue Bridge Cup 1.) about a few

Title: for an integer, the number that can divide the integer is called the divisor of the number. For example: 1, 2, 3, 6 Are divisors of 6. How many divisors does 78120 have. Answer: 96

Idea:

public class Main { public static void main(String[] args) { int flag = 0; for (int i = 1; i <= 78120; i++) { if (78120%i == 0) flag++; } System.out.print(flag); } }

### II. Maximum common factor

1, Rolling phase division

characteristic:

- m. N is a natural number and M > n
- Let r = m%n
- If r = 0, then n is the greatest common factor of m and N, otherwise proceed to the next step
- Repeat (2) (3) with M = n and N = R until r = 0 to find the maximum common factor

public static int gcd (int n,int m){ //Default m > n int r = m%n; if (r == 0) return n; else { while (r != 0){ m = n; n = r; r = m%n; } } return n; }

### 2, Stein algorithm

characteristic:

## 3. Sequence (high school knowledge)

### I. recursive sequence (Fibonacci)

Features: if the relationship between the nth item of the sequence {a[n]} and its previous item or items can be expressed by a formula, then this formula is called the recurrence formula of the sequence.

Typical example: Fibonacci sequence

Title: finding the nth term of Fibonacci sequence

public static int Fibonacci (int n) { if (n == 0 || n == 1) return n; else return Fibonacci (n-1) + Fibonacci (n-2); }

Typical example: cows give birth to calves

Title: there is a cow. It gives birth to a heifer every year. Each heifer starts from the fourth year and gives birth to a heifer at the beginning of each year. Please program how many cows are there in the nth year?

public static int ox (int year) { if (year <= 4) return year; else return ox (year-1) + ox (year-3); }

### II. Isochronous sequence (only isochronous isochronous sequence is involved, and most of them can be calculated manually)

Features: the latter minus the former equals a constant, i.e. F(n)-F(n-1) = d (d is a constant)

General term formula: F(n) = F(1) + (n-1) * d

Mean term of equal difference: F(n) = (F(n+1) + F(n-1))/2

Sum of the first n items: S(n) = (F(1) + F (n)) * n/2

### III. equal ratio sequence

Features: the latter term is equal to a constant than the former term, that is, F(n)/F(n-1) = q (q is a constant)

General term formula: F(n) = F(1) * pow(q,n-1)

Sum of the first n items: S(n) = F(1) * (1 - pow(q,n))/(1-q)

## 4. Factorial

Features: n= 12345*…*n

Recursion or loop:

//recursion public static int factorial (int n){ if (n == 1) return 1; else return factorial (n-1); } //loop public static int factorial (int n){ int sum = 1; for (int i = 1; i <= n; i++){ sum = sum*n; } return sum; }

## 5. Full Permutation (DFS + backtracking)

Features: the arrangement focuses on the order, that is, the arrangement of all elements in different order within all specified elements

Core code:

//Total permutation from m-n public static int[] num = new int [10000]; public static int[] jug = new int [100]; public static void dfs (int m,int n) { if (m > n) { for (int i = 1;i < m;i ++) { System.out.print(" "+num[i]); } System.out.println(); return ; } else { for (int i = 1; i <= n;i ++) { if (jug[i] == 0) { jug[i] = 1; //Mark if you enter this layer num[m] = i; dfs (m+1,n); //Go to the next floor jug[i] = 0; //to flash back } } } }

## 10. Location problem

Description: take each digit of a number for operation

Core code:

while (x != 0){ num = x%10; Perform the required operations; x = x/10; }

### I. (the 11th Blue Bridge Cup 2.) doorplate making

Idea:

public class Main { //How many in 1-2020 2 public static void main(String[] args) { int flag = 0; int num; for (int i = 1;i <= 2020; i ++) { int x = i; // Get x receive I else into an endless loop while (x != 0) { num = x%10; if (num == 2) //Operate on each bit taken flag++; x = x/10; } } System.out.print(flag); } }

# 2, Thoughts and Strategies

## 1. Backtracking algorithm

### Ⅰ. (leetcode 1688) number of matches in the competition

Title: give you an integer n ，Indicates the number of teams in the competition. The competition follows a unique competition system: If the current number of teams is even, each team will be paired with another team. Total n / 2 Games, and produce n / 2 Two teams entered the next round. If the current number of teams is odd, it will randomly empty and advance to one team, and the other teams will be paired. total Altogether (n - 1) / 2 Games, and produce (n - 1) / 2 + 1 Two teams entered the next round. Returns the number of matches made in the game until the winning team is determined. Input: n = 7 Output: 6 Explanation: competition details: - Round 1: number of teams = 7 ，Pairing times = 3 ，4 Detachment Wu was promoted. - Round 2: number of teams = 4 ，Pairing times = 2 ，2 Detachment Wu was promoted. - Round 3: number of teams = 2 ，Pairing times = 1 ，Decide on a winning team. Total pairing times = 3 + 2 + 1 = 6

Idea: the first one: simple simulation according to the meaning of the question (Likou question bank classification is a backtracking algorithm, but I don't know where to reflect the backtracking.)

The second: the answer to the big guy's Mathematical Thinking: there are n teams and one champion, and N-1 teams need to be eliminated. One team was eliminated in each game, so n-1 games were played. So there are n-1 pairs.

//First kind public static int numberOfMatches(int n) { int x = 0; while (n > 1) { if (n%2 == 0) { n = n/2; x = x+n; } else { n = (n-1)/2; x = x+n+1; } } return x; }

//Second public int numberOfMatches(int n) { return n-1; }

## 2. Greedy algorithm

### I. (leetcode 1518) wine change problem

Title: the convenience store in the community is promoting sales. Use numExchange An empty bottle can be exchanged for a new bottle of wine. You bought it numBottles A bottle of wine. If you drink the wine in the bottle, the bottle will become empty. Please calculate the maximum number of bottles you can drink. Input: numBottles = 9, numExchange = 3 Output: 13 Explanation: you can exchange three empty wine bottles for one bottle of wine. So you can drink up to 9 + 3 + 1 = 13 A bottle of wine.

Idea: the first method: first, add the wine exchanged for the first time to the wine exchanged for the first time, then calculate the wine convertible for the first time and the remaining wine that is not enough to be exchanged, and then calculate the number of wine bottles exchanged for the next time by adding the two

Second: greedy algorithm, that is, first use res to record the number of drinks you drink for the first time, and numExchange can be changed. Therefore, each time you use numExchange to change one, you use res to record one. After numExchange is changed, the change itself is a bottle. Therefore, the next numExchange-1 cycle will continue until numbolts < numExchange stops (the boss instructed me to understand!)

//First kind public static int numWaterBottles(int numBottles, int numExchange) { int res = numBottles; while (numBottles >= numExchange) { res = res + numBottles/numExchange; numBottles = numBottles/numExchange + numBottles%numExchange; } return res; } //Second public static int numWaterBottles(int numBottles, int numExchange) { int res = numBottles; while (numBottles >= numExchange) { numBottles = numBottles - numExchange + 1; res ++; } return res; }

### II. (leetcode 455) distribute biscuits

Title: suppose you are a great parent and want to give your children some cookies. But every child is the best You can only give one more cookie. For every child i，All have an appetite value g[i]，This is the smallest size of biscuits that can satisfy children's appetite Inch; And every cookie j，All have one size s[j] . If s[j] >= g[i]，We can put this cookie j Assign to children i ，The child will be satisfied. Your goal is to meet as many children as possible and output this Maximum value. input: g = [1,2,3], s = [1,1] output: 1 explain: You have three children and two biscuits. The appetite values of the three children are: 1,2,3. Although you have two small biscuits, because their size is 1, you can only satisfy children with an appetite of 1. So you should output 1.

Idea: sort first, let each child with the smallest appetite value eat first, then record, and finally return the value

public int findContentChildren(int[] g, int[] s) { int i = 0,j = 0; // i points to the appetite value and j points to the cookie size int gl = g.length,sl = s.length; Arrays.sort (g);Arrays.sort(s); while (j < sl && i < gl){ //Pay attention to the logical relationship here! if (s[j] >= g[i]) { i++; } j++; } return i; }

### III. (leetcode 1827) increment the array with the least operation

Title: give you an integer array nums (Subscripts start at 0). In each operation, you can select an element in the array and increase it by 1. For example, if nums = [1,2,3] ，You can choose to increase nums[1] obtain nums = [1,3,3] . Please return to make nums Strictly increasing the minimum number of operations. We call it an array nums Is strictly increasing when it satisfies for all zeros <= i < nums.length - 1 all yes nums[i] < nums[i+1] . An array of length 1 is a special case of strictly increasing. Input: nums = [1,1,1] Output: 3 Explanation: you can do the following: 1) increase nums[2] ，Array becomes [1,1,2] . 2) increase nums[1] ，Array becomes [1,2,2] . 3) increase nums[2] ，Array becomes [1,2,3] .

Idea: traverse the array and compare it in pairs. If it is not satisfied, add it and record it every time you add a flag (two cycles lead to low efficiency)

public static int minOperations(int[] nums) { int i = 0,flag = 0; for (i = 0; i < nums.length; i++){ while (nums[i] >= nums[i+1]){ nums[i+1]++; flag++; } } return flag; }

The second way of thinking: compare two items. If the latter item is smaller than the previous one, subtract it. Add up the subtracted numbers and make the latter number 1 larger than the previous one, and then return the sum of the addends

public static int minOperations(int[] nums) { int i = 0,flag = 0; for(i = 0; i < nums.length-1;i ++){ if (nums[i] >= nums[i+1]){ flag = flag + (nums[i] - nums[i+1])+1; nums[i+1] =nums[i]+1; } } return flag; }

### IV. (leetcode 122) the best time to buy and sell stocks II

Title: given an array prices ，among prices[i] Is a given stock i Day price. Design an algorithm to calculate the maximum profit you can make. You can complete as many transactions as possible (buying and selling a stock multiple times). Note: you cannot participate in multiple transactions at the same time (you must sell the previous shares before buying again). Example 1: input: prices = [7,1,5,3,6,4] output: 7 explain: On day 2 (stock price) = 1)When buying, on day 3 (stock price) = 5)Sell at, The exchange is profitable = 5-1 = 4 . Then, on day 4 (stock price) = 3)When buying, on day 5 (stock price) = 6)Sell at, The exchange is profitable = 6-3 = 3 .

Idea: compare two by two and always buy the stock that is bigger the next day than the first day

public int maxProfit(int[] prices) { int getMoney = 0; for (int i = 0; i < prices.length-1;i ++){ if (prices[i] < prices[i+1]) getMoney += prices[i+1] - prices[i]; } return getMoney; }

### V. (leetcode 1716) calculate the power to deduct money from the bank

Title: Hercy He wants to save money for his first car. He saves money in the Li Kou bank every day. At first, he deposited 1 yuan on Monday. From Tuesday to Sunday, he deposited 1 yuan more every day than the previous day. Next Monday, he deposited 1 yuan more than the previous Monday. Here you are n ，Please go back to the n At the end of the day, how much money did he deposit in Likou bank. Example 1: Input: n = 4 Output: 10 Explanation: after the 4th day, the total amount is 1 + 2 + 3 + 4 = 10 .

Idea: because the range given by n is [11000], I can save 1001 numbers hahaha for him in advance, and then I will add the numbers of the array

public int totalMoney(int n) { int[] bank = new int[1001]; int week = 7,arrNum = 0,sumMoney = 0; for (int i = 0; i < 143; i++){ for (int j = i+1; j < week + 1; j++ ){ bank[arrNum] = j; arrNum++; } week++; } for (int i = 0; i < n; i ++){ sumMoney += bank[i]; } return sumMoney; }

The second idea:

## 3. Divide and conquer algorithm

### Ⅰ. (leetcode 169) most elements

Title: given a size of n Find most of the elements in the array. Most elements refer to the elements in the array Current times greater than ⌊ n/2 ⌋ Element. You can assume that the array is non empty and that there are always many elements in a given array. Input:[3,2,3] Output: 3

Idea: the first one: force buckle is called Moore voting, which I call violent simulation! Start with the first element. If the comparison with the next element is the same, the flag is recorded below. If it is different, reset the flag to 1 from the different element (because it is itself a reset to 0 when submitted before. Why not) If flag > num.length, this element is output

The second is the official solution. The divide and conquer algorithm (it's useless if you feel a little troublesome. It should be my food). If the number a is the mode of the array num, if we divide num into two parts, then a must be at least part of the mode.

We can prove this conclusion by using the counter proof method. Assuming that a is neither the mode of the left half nor the mode of the right half, then a appears less than L / 2 + r / 2 times, where l and r are the lengths of the left half and the right half respectively. Because l / 2 + r / 2 < = (L + r) /2. Note that a is not the mode of array nums, so there is a contradiction. Therefore, this conclusion is correct.

In this way, we can use divide and conquer to solve this problem: divide the array into left and right parts, calculate the mode a1 of the left half and the mode a2 of the right half respectively, and then select the correct mode from a1 and a2.

//First kind public int majorityElement(int[] nums) { int accept = nums[0]; int nl = nums.length; int flag = 0,res = 0; for (int i = 0; i < nl; i++) { if (accept != nums[i]) { accept = nums[i]; flag = 1; //Reset to 1 } else { flag ++; if (flag >= nl/2) { res = accept; break; } } } return accept; }

//Second private int countInRange(int[] nums, int num, int lo, int hi) { int count = 0; for (int i = lo; i <= hi; i++) { if (nums[i] == num) { count++; } } return count; } private int majorityElementRec(int[] nums, int lo, int hi) { // base case; the only element in an array of size 1 is the majority // element. if (lo == hi) { return nums[lo]; } // recurse on left and right halves of this slice. int mid = (hi - lo) / 2 + lo; int left = majorityElementRec(nums, lo, mid); int right = majorityElementRec(nums, mid + 1, hi); // if the two halves agree on the majority element, return it. if (left == right) { return left; } // otherwise, count each element and return the "winner". int leftCount = countInRange(nums, left, lo, hi); int rightCount = countInRange(nums, right, lo, hi); return leftCount > rightCount ? left : right; } public int majorityElement(int[] nums) { return majorityElementRec(nums, 0, nums.length - 1); }

## 4. Pruning (combinatorial problem)

### I. combinatorial problems

Features: select m numbers from n numbers for combination (regardless of the order in the combination)

Core code: (the template written by the big guys in the Blue Bridge Cup group)

import java.util.Arrays public static void dfs (int start,int index,int[] a,int[] b){ if (index + (a.length - start)) // prune return ; if (index == b.length){ //When full, output array b System.out.println(b); return ; } for (int i = start; i <= a.length; i ++){ b[index] = a[i]; dfs (i + 1,index + 1,a,b); // Go to the next floor } }

## 5. Memorization

### Ⅰ. (leetcode 1480) dynamic sum of one-dimensional arrays

subject:Give you an array nums . array「Dynamic and」The calculation formula is: runningSum[i] = sum(nums[0]...nums[i]) . Please return nums The dynamics and. Example 1: Input: nums = [1,2,3,4] Output:[1,3,6,10] Explanation: the dynamic and calculation process is [1, 1+2, 1+2+3, 1+2+3+4] .

Idea: when I saw the title, I didn't think of violence at first sight... When I saw that there was a part in the explanation that coincided with the previous item, I directly asked him to add the previous item (the previous item has met the title conditions) and so on

public int[] runningSum(int[] nums) { for (int i = 1;i < nums.length; i ++){ nums[i] = nums[i-1]+nums[i]; } return nums; }

## 6. Dynamic planning

# 3, Data structure class

## 1.

### Ⅰ.

# 4, Comprehensive class

## 1.

### Ⅰ.

# 5, Mathematics (feeling optimization)

## preface

Give yourself: do all the simple and difficult mathematical problems in the force button, and the goal is to do them, and then reduce the time complexity of the code And the degree of simplification are at the limit of their own level in order to feel what optimization is

### I. (leetcode 1512) number of good number pairs

Title: give you an integer array nums . If a set of numbers (i,j) satisfy nums[i] == nums[j] And i < j ，You can think of this as a group of good number pairs. Returns the number of good pairs. Input: nums = [1,2,3,1,1,3] Output: 4 Explanation: there are 4 groups of good pairs, which are (0,3), (0,4), (3,4), (2,5) ，Subscript starts at 0

Idea: bubble sorting idea

public int numIdenticalPairs(int[] nums) { int flag = 0; for (int i = 0; i < nums.length-1; i++){ for (int j = i+1; j < nums.length; j++){ if (nums[i] == nums[j]) flag++; } } return flag; }

Ideas after optimization:

### Ⅱ. (leetcode 1822) symbol of array element product

Title: known functions signFunc(x) Will be based on x Returns a specific value: If x Is a positive number and returns 1. If x Is a negative number, return -1 . If x Is equal to 0 and returns 0. Give you an array of integers nums . order product For array nums The product of all element values in. return signFunc(product) . Example 1: Input: nums = [-1,-2,-3,-4,3,2,1] Output: 1 Explanation: the product of all values in the array is 144, and signFunc(144) = 1

Idea: judge whether there is 0. If there is 0, directly return 0. Conversely, judge the number of negative numbers. If negative numbers are odd, the whole is negative, and vice versa

public int arraySign(int[] nums) { int up = 0,down = 0,judge = 0; for (int num: nums){ if (num == 0){ judge = 0; break; } else if (num < 0){ down++; if (down%2 == 0) judge = 1; else judge = -1; } else judge = 1; } return judge; }

### Ⅲ. (leetcode 1281) difference of bit product sum of integer

Title: give you an integer n，Please help calculate and return the integer「Product of figures」And「Sum of figures」Poor. Input: n = 234 Output: 15 Explanation: Product of numbers = 2 * 3 * 4 = 24 Sum of your numbers = 2 + 3 + 4 = 9 result = 24 - 9 = 15

Idea: use while to take bit, quadrature and sum, and finally product and subtract (the code written by the first reaction)

public int subtractProductAndSum(int n) { int product = 1,sum = 0; int num,x = n; //Multiply while (x != 0){ num = x%10; product *= num; x = x/10; } //Add while (x != 0){ num = x%10; sum += num; x = x/10; } return (product - sum); }

Idea after optimization: only one while is required

public int subtractProductAndSum(int n) { int product = 1,sum = 0,num; while (n != 0){ num = n%10; product *= num; sum += num; n = n/10; } return (product - sum); }

### Ⅳ. (leetcode 1281) maximum number composed of 6 and 9

Give you a positive integer consisting only of numbers 6 and 9 num. You can only flip one digit at most to turn 6 into 9, or 9 into 6. Please return the maximum number you can get. Example 1: Input: num = 9669 Output: 9969 Explanation: Change the first digit to get 6669. Change the second digit to get 9969. Change the third digit to get 9699. Change the fourth digit to get 9666. The largest number is 9969.

Idea: while is too troublesome to get from low to high, so it is not considered to use while. Therefore, getting from high to low should be transformed into a string, and then '6' should be changed to '9' for the first time, and then break

public int maximum69Number (int num){ StringBuilder sb = new StringBuilder(String.valueOf(num)); for (int i = 0;i < sb.length();i ++){ if (sb.charAt(i) != '9') { sb.setCharAt(i, '9'); break; } } return Integer.parseInt(sb.toString()); }

### V. (leetcode 1551) the minimum operand that makes all elements in the array equal

Title: there is a length of n Array of arr ，among arr[i] = (2 * i) + 1 ( 0 <= i < n ). In one operation, you can select two subscripts as x and y ( 0 <= x, y < n )And make arr[x] Minus 1 arr[y] Add 1 (i.e arr[x] -=1 And arr[y] += 1 ). The ultimate goal is to make all elements in the array equal. The test case will ensure that all elements in the array can eventually be equal after several steps. Give you an integer n，That is, the length of the array. Please return the array arr The minimum operand required for all elements in the to be equal. Example 1: Input: n = 3 Output: 2 Explanation: arr = [1, 3, 5] First operation selection x = 2 and y = 0，Make array [2, 3, 4] The second operation continues x = 2 and y = 0，The array will become [3, 3, 3] Example 2: Input: n = 6 Output: 9

Idea: the law can be found by listing the first 6 items. When n > = 2, his even items are the sum of the even items of the first n items from 1 + to N, and when n=3, his odd items are the sum of the odd items of the first n items from 1 + to n (comparison)

public int minOperations(int n) { int res = 0,num = n/2; if (n == 1) res = 0; if (n%2 == 0) { res = num * num; } else if (n%2 != 0 && n >= 3){ res = num*num+num; } return res; }

Optimized idea (force deduction official): (I really didn't expect this rounding (nn-1)/4 =[nn/4])

public int minOperations(int n) { return n * n / 4; }

### Vi. (leetcode interview question 16.07) maximum value

Title: write a method to find two numbers a and b The largest one in the shall not be used if-else Or other comparison operators. Example: Input: a = 1, b = 2 Output: 2

Idea: use mathematical formula to prove the following

public int maximum(int a, int b) { return (int)(((long)a+(long)b+Math.abs((long)a-(long)b))/2); }