Solutions to the exercises of the 10th provincial competition of group B of C language in 2019 of Blue Bridge Cup

Posted by ksas025 on Tue, 08 Mar 2022 05:06:16 +0100


Reprint blog: https://cloud.tencent.com/developer/article/1408608

Question A: form A team

Total score of this question: 5 points
As a basketball team coach, you need to choose one player from position 1 to position 5 from the following list,
Form the team's starting lineup.
The score of each player from position 1 to position 5 is shown in the table below. Please calculate the starting lineup 1
What is the maximum possible sum of the scores from position to position 5?

This is to take the player with the highest score in a certain position. Of course, it should be noted that a player can only occupy one position, not multiple positions at the same time.

Answer: 490

Question B: year string

Total score of this question: 5 points
Xiao Ming uses the letter A to correspond to the number 1, B to correspond to 2, and so on, and Z to correspond to 26. For 27
For the above numbers, Xiao Ming uses a string of two or more bits to correspond, for example, AA corresponds to 27 and AB pairs
It should be 28, AZ corresponds to 52 and LQ corresponds to 329.
What is the string corresponding to 2019?
[answer submission]
This is a question filled in with results. You just need to calculate the results and submit them. The result of this question is one
An English string in uppercase. Only fill in this string when submitting the answer. Pay attention to all uppercase and fill in more
The rest of the content will not be scored.

This question is to use A~Z to represent the numbers 1 ~ 26, and then use the 26 letters A~Z to represent 2019. In fact, it is similar to hexadecimal conversion. The code:

#include <iostream>
using namespace std;
void solve(int n) {
	if (!n) {
		return ;
	}
	solve(n / 26);
	cout << (char)(n % 26 + 64);
}

int main() {
	solve(2019);
	return 0;
} 

Answer: BYQ

Question C: sequence evaluation

Total score of this question: 10 points

Given the sequence 1, 1, 1, 3, 5, 9, 17,..., starting from item 4, each item is the sum of the first three items. seek
The last four digits of item 20190324.
[answer submission]
This is a question filled in with results. You just need to calculate the results and submit them. The result of this question is one
A 4-digit integer (hint: the thousand digit of the answer is not 0). When submitting the answer, only fill in this integer and fill in
Extra content will not be scored.

It is similar to the nth item of Fibonacci sequence, but the recursive formula has changed, and recursion cannot be used, otherwise the stack will explode. Another problem is that the direct calculation to item 20190324 will definitely overflow, and the remainder operation should be carried out in the calculation process. code:

#include <iostream>
using namespace std;

int solve(int n) {
	if (n <= 3) {
		return 1;
	}
	int a = 1, b = 1, c = 1, res;
	for (int i = 4; i <= n; i++) {
         // Remember to take the rest here
		res = (a + b + c) % 10000;
		a = b;
		b = c;
		c = res;
	}
	return res;
}
int main() {
	cout << solve(20190324) << endl;
	return 0;
}

Answer: 4659

Question D: decomposition of numbers

Total score of this question: 10 points

[problem description]
2019 is decomposed into the sum of three different positive integers, and each positive integer is required not to be wrapped
Including the numbers 2 and 4, how many different decomposition methods are there?
Note that the order in which three integers are exchanged is considered the same method, such as 1000 + 1001 + 18 and
1001 + 1000 + 18 are considered the same.
[answer submission]
This is a question filled in with results. You just need to calculate the results and submit them. The result of this question is one
An integer. Only fill in this integer when submitting the answer. If you fill in the extra content, you will not be able to score.

However, we should pay attention to the problem of de duplication. When the questions are in different order and the numbers are the same, we can only count one kind. During the competition, we really think this problem is simple, thinking that only one tag array can be de duplicated. What we don't know is that there may be such a situation: suppose a + b + c ==2019, and then assume d + e + f == 2019, If a + d + f == 2019 at this time, this can be regarded as a new situation, but if only one tag array is used, it will be considered that the three numbers a, D and F have all appeared, that is, this situation is omitted. Here, I will form a, B and C into a new number in the form of hexadecimal operation, and then put it in the mark array. If the next number conforms to a + b + c ==2019, they will also form a new number, and then find it in the existing mark array. If it is found, it is proved to be coincident. Otherwise, it is a new case, and it will be recorded in the mark array.

The above is the previous idea. I think the problem is complicated. Thanks to the correction of the small partner in the comment area, we can enumerate the three variables (assuming a, b and c) from 1, that is, violence. The result will be repeated. The reason for the repetition is that a May coincide with b and c. similarly, b may coincide with a and c, and c may coincide with a and b. That is, you need to divide the result by 6.

Another simpler idea is to control the starting values of a, b and c during the cycle, that is, a starts from 1, b starts from a + 1, and c starts from b + 1. In this way, a, b and c will not be equal, and there will be no repetition, because at least one number of a, b and c obtained in each cycle is different from that of a, b and c before. The result obtained in this way is the final result. In terms of time complexity, the second idea is faster than the first. code:

#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
// Judge whether a digit contains 2 and 4 
bool judge(int n) {
	int t;
	while (n) {
		if (((t = n % 10) == 2) || t == 4) {
			return true;
		}
		n /= 10;
	}
	return false;
}

bool check(int a, int b, int c) {
	// If a number appears 2 and 4, or a duplicate number appears, return 0 
	if (judge(a) || judge(b) || judge(c) || 
		a == b || a == c || b == c) {
		return false;
	}
	return true;
}

/**
 * The first idea: directly enumerate the results / 6
 */
int main() {
	int res = 0;
	for (int i = 1; i < 2018; i++) {
		for (int j = 1; j < 2018; j++) {
			for (int k = 1; k < 2018; k++) {
				if (i + j + k == 2019) {
					res += check(i, j, k);
				}
			}
		}
	}
	cout << (res / 6) << endl;
	return 0;
} 
/**
 * The second idea: the starting value of the control variable during the cycle:
 */
int main() {
	int res = 0;
	for (int i = 1; i < 2018; i++) {
		for (int j = i + 1; j < 2018; j++) {
			for (int k = j + 1; k < 2018; k++) {
				if (i + j + k == 2019) {
					res += check(i, j, k);
				}
			}
		}
	}
	cout << res << endl;
	return 0;
} 

Answer: 40785

Question E: Maze

Total score of this question: 15 points
[problem description]
The following figure shows the plan of a maze, in which the one marked with 1 is an obstacle and the one marked with 0 is an obstacle
A place to pass.
010000
000100
001001
110000
The entrance of the labyrinth is the upper left corner and the exit is the lower right corner. In the labyrinth, you can only walk from one position
One of its four directions: up, down, left and right.
For the above maze, start from the entrance and pass through the maze in the order of DRRURRDDDR,
A total of 10 steps. Where D, U, L and R respectively represent going down, up, left and right.
For this more complex maze (30 rows and 50 columns), please find a way through the maze,
It uses the least number of steps. On the premise of the least number of steps, please find the one with the smallest dictionary order as the answer.
Please note that in the dictionary order, d < l < R < U. (if you copy the following text into a text file, please be sure to
It is necessary to check whether the copied content is consistent with that in the document. There is a file maze in the test question directory txt,
(same as the text below)
01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000
[answer submission]
This is a question filled in with results. You just need to calculate the results and submit them. The result of this question is one
A string containing four letters D, U, L and R. only fill in this string when submitting the answer
Writing extra content will not score.

How to put map data into code is a problem, which is usually replaced by text. It's a classic pathfinding problem. DFS is used in the game. The program has been running for nearly an hour without an answer... Finally, the stack exploded. Such a large amount of data should have been thought of long ago. Use BFS instead, because the solution obtained by BFS is always the optimal solution, that is, the solution with the least number of steps. When traversing, we traverse in four directions from small to large according to the dictionary order:

#include <iostream>
#include <cstdio>  
using namespace std;

int map[][50] = {
	0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 
    0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 
    0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 
    0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 
    0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 
    1, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 
    0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 
    1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 
    0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 1, 
    1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 
    0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 
    1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 
    0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 
    1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 
    1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 1, 
    1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 
    1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 0, 1, 
    0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 
    1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 0, 
    0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 
    1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 
    0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 
    1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 1, 0, 
    0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 
    1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 
    0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 
    1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 
    1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 
    0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 1, 
    1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0
};
const int n = 30, m = 50;
int res = 0x7fffffff;
int book[n][m];

struct node {
	int x;
	int y;
	int s; // distance 
	int f; // Subscript a position 
	char ch; // Previous direction 
};
node que[n*m];
int head, tail;
// In dictionary order, from small to large
int next_[4][2] = {
    {1, 0}, //lower
    {0, -1}, // Left
    {0, 1}, // right
    {-1, 0} // upper
};

void print(int index) {
	if (index == 0) {
		return ;
	}
	print(que[index].f);
	cout << que[index].ch;
}

void bfs() {
	que[tail].x = 0;
	que[tail].y = 0;
	que[tail].s = 0;
	que[tail].f = -1;
	que[tail++].ch = 0;
	book[0][0] = 1;
	int flag = 0;
	
	while(head < tail) {
		int nX, nY;
		for(int i = 0; i < 4; i++) {
			nX = next_[i][0] + que[head].x;
			nY = next_[i][1] + que[head].y;
			if (nX < 0 || nX >= n || nY < 0 || nY >= m) {
				continue;
			}
			if (map[nX][nY] == 0 && book[nX][nY] == 0) {
				book[nX][nY] = 1;
				que[tail].x = nX;
				que[tail].y = nY;
				que[tail].s = que[head].s + 1;
				que[tail].f = head;
				if (next_[i][0]) {
					que[tail].ch = (next_[i][0] == 1 ? 'D' : 'U');
				} else if (next_[i][1]) {
					que[tail].ch = (next_[i][1] == 1 ? 'R' : 'L');
				}
				tail++;
				// Find the exit 
				if(nX == n - 1 && nY == m - 1) {
					flag = 1;
					break;
				}
			}
		}
		if (flag == 1) {
			break;
		}
		head++;
	}
	print(tail - 1); 
}

int main() {
	bfs();
	
	return 0;
}

Answer: ddddrurrrrrrrrrrrrrrrrrrddddddddrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrdrdllldddldddldddlddrrrrrrrrrrrrrrrrrdddrr

Question F: sum of special numbers

Time limit: 1.0s memory limit: 256.0MB total score of this question: 15 points
[problem description]
Xiao Ming is very interested in numbers containing 2, 0, 1 and 9 (excluding the leading 0), from 1 to
Such numbers in 40 include 1, 2, 9, 10 to 32, 39 and 40, a total of 28, and their sum is 574.
What is the sum of all such numbers in 1 to n?
[input format]
The input line contains two integers n.
[output format]
Output a line containing an integer representing the sum of the numbers that meet the conditions.
[sample input]
40
[sample output]
574
[evaluation case scale and agreement]
For 20% of the evaluation cases, 1 ≤ n ≤ 10.
For 50% of the evaluation cases, 1 ≤ n ≤ 100.
For 80% of the evaluation cases, 1 ≤ n ≤ 1000.
For all evaluation cases, 1 ≤ n ≤ 10000.

The main purpose of this question is to find out all the numbers with one of the four numbers 2, 0, 1 and 9 in a certain range of digits. I feel that it is regular, too lazy to find it, and direct violence. The maximum range is 10000. The O(n) complexity should be acceptable. Code:

#include <iostream>
using namespace std;

// Judge whether a digit contains 2, 0, 1 and 9 
bool judge(int n) {
	int t;
	while (n) {
		if (((t = n % 10) == 2) || t == 0 || t == 1 || t == 9) {
			return true;
		}
		n /= 10;
	}
	return false;
}

int main() {
	int n, res = 0;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		if (judge(i)) {
			res += i;
		}
	}
	cout << res << endl;
	
	return 0;
}

Question G: weight of complete binary tree

Time limit: 1.0s memory limit: 256.0MB total score of this question: 20 points
[problem description]
Given a complete binary tree with N nodes, each node in the tree has a weight, press from
The sequence of ·· A and ·· 2 is from left to bottom, as shown in the following figure:
Now Xiao Ming wants to add up the weights of nodes with the same depth. He wants to know which depth node
Maximum sum of weights? If the weight sum of multiple depths is the largest, please output the smallest depth.
Note: the depth of the root is 1.
[input format]
The first line contains an integer N.
The second line contains N integers a 1, a 2, ···· A N.
[output format]
Output an integer representing the answer.
[sample input]
7
1 6 5 4 3 2 1
Test question G: weight of complete binary tree 10
Group B of the 10th Blue Bridge Cup software provincial competition C/C + + University
[sample output]
2
[evaluation case scale and agreement]
For all evaluation cases, 1 ≤ N ≤ 100000, − 100000 ≤ A i ≤ 100000.

It is not difficult to understand the characteristics of a complete binary tree. The maximum number of nodes in layer I of a complete binary tree is 2^(i-1). For a subscript element, we only need to know which layer it belongs to, because the given data range is within 100000 nodes. How many layers does a complete binary tree composed of so many nodes have? We know that the relationship between the total number of nodes and depth of a complete binary tree is that a complete binary tree with depth n has at most 2^n - 1 nodes, that is, when the complete binary tree is a full binary tree, the number of nodes is the largest. The maximum number of nodes of a complete binary tree with 17 layers is 2 ^ 17 - 1 = 131071, which is greater than the given range of N, so it is very simple for us to calculate the depth layer of each node, and then make statistics. Because the depth of the root given in the title is 1, the depth we calculate needs to be moved back one bit, that is, the maximum depth is 18. Here is the code:

#include <iostream>
#include <cstdio>
using namespace std; 
const int MAX_DEEP = 18;
long long temp[MAX_DEEP + 1];

// Gets the depth of the node with subscript n 
int getDeep(int n) {
	int res = 0;
	while (n > 0) {
		n /= 2;
		res++;
	} 
	return res;
}
int main() {
	int n, t;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		scanf("%d", &t);
		// Find the depth layer to which the current node belongs and add it to the weight sum of the current depth layer node 
		temp[getDeep(i)] += t;
	} 
	int res = 0x80000000, resDeep;
	// Node weight and maximum depth layer 
	for (int i = 1; i <= MAX_DEEP; i++) {
		if (temp[i] > res) {
			res = temp[i];
			resDeep = i;
		}
	}
	cout << resDeep << endl;
	return 0;
}

Question H: arithmetic sequence

Time limit: 1.0s memory limit: 256.0MB total score of this question: 20 points
[problem description]
The math teacher gave Xiao Ming a problem of summing the arithmetic sequence. But the careless Xiao Ming forgot one
Part of the sequence, only remember N integers.
Now give these N integers. Xiao Ming wants to know what is the shortest arithmetic sequence containing these N integers
How many?
[input format]
The first line of input contains an integer N.
The second line contains N integers A 1, a 2, ····, A N. (note that A 1 ∼ A N is not necessarily an equal difference
(the order in the column is given)
[output format]
Output an integer to represent the answer.
[sample input]
5
2 6 4 10 20
[sample output]
10
[example description]
The shortest arithmetic sequence containing 2, 6, 4, 10 and 20 is 2, 4, 6, 8, 10, 12, 14, 16
18,20.

[evaluation case scale and agreement]
For all evaluation cases, 2 ≤ N ≤ 100000, 0 ≤ A i ≤ 10 9.

This problem feels a little simple. I don't know if there is a pit. The idea is to find out the minimum tolerance in the given number, and then divide the maximum number - minimum number in the number by 2 and add 1. Pay attention to the treatment when the tolerance is 0.

Add: I fell into the pit. Thank you for pointing out that the correct idea should be to de duplicate the given numbers before sorting, and the tolerance should be to find the maximum common divisor of the difference between all adjacent numbers after sorting. Thanks again to the partners in the comment area. The corrected code is:

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;

int value[100010]; 
bool mark[100010];

int gcd(int a, int b) {
	int t;
	while (a) {
		t = a;
		a = b % a;
		b = t;
	}
	return b;
}

int main() {
	int n, d, len = 0, t;
	int maxx = 0, minn = 0x7fffffff;
	cin >> n;
	for (int i = 0; i < n; i++) {
		scanf("%d", &t);
		// Ensure that each number appears only once 
		if (!mark[t]) {
			mark[t] = 1;
			value[len++] = t; 
			maxx = max(maxx, t);
			minn = min(minn, t);
		}
	}
	sort(value, value + len);
	if (len <= 1) {
		cout << n << endl;
	} else {
		// Find the maximum common divisor of all tolerances 
		d = value[1] - value[0];
		for (int i = 2; i < len; i++) {
			d = gcd(d, value[i] - value[i-1]);
		}
		cout << ((maxx - minn) / d + 1) << endl; 
	}
	
	return 0;
} 

Question I: suffix expression

Time limit: 1.0s memory limit: 256.0MB total score of this question: 25 points
[problem description]
Given n plus signs, M minus signs and N + M + 1 integers, a 1, a 2, ···, A N+M+1, small
Ming wants to know that in all the legal numbers rounded up by these n plus signs, M minus signs and N + M +1 integers
In the suffix expression, which one has the largest result?
Please output this maximum result.
For example, if 1 2 3 + -, the result of the suffix expression "2 3 + 1 -" is 4, which is the largest.
[input format]
The first line contains two integers N and M.
The second line contains N + M + 1 integers a 1, a 2, ···, A N+M+1.
[output format]
Output an integer representing the answer.
[sample input]
1 1
1 2 3
[sample output]
4
[evaluation case scale and agreement]
For all evaluation cases, 0 ≤ N, M ≤ 100000, − 10 9 ≤ A i ≤ 10 9.

This question was a little confused at the beginning, but it was blinded by the concept of suffix expression. Conceptually, the meaning of suffix expression should be the same as that of infix expression. Think about the familiar infix expression, we can freely customize the order of digital operation, so the suffix expression should also have this ability, that is, we can combine the operation order at will, We know the concept. The second point is that if there are only +, - operators, then all numbers can be regarded as addition, and the - operator can be regarded as negative sign. Then the topic can be regarded as adding N + M + 1 numbers, but there must be m numbers that become their own opposite numbers. It is easy for us to think that we can turn negative numbers into their opposite numbers and become positive numbers. The order should be to turn the negative number with the largest absolute value into positive numbers first, and then other numbers. We also need to discuss the relationship between the number of negative numbers and M: 1. The number of negative numbers in a given number itself is less than M. in this case, there are several negative numbers with the smallest absolute value. 2. The number of negative numbers in a given number itself is greater than m, which is similar to 1. 3. The number of negative numbers in a given number itself is equal to m, which is all positive and everyone is happy. Finally, just add. Here is the code:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;

const int MAXN = 200020;
int nums[MAXN];

// User defined sorting function: sort by absolute value from large to small 
bool com(int a, int b) {
	return abs(a) > abs(b);
}

int main() {
	int N, M;
	cin >> N >> M;
	int n  = N + M + 1;
	long long res = 0;
	for (int i = 0; i < n; i++) {
		scanf("%d", nums + i);
	}
	sort(nums, nums + n, com);
	// Change a negative number to a positive number 
	for (int i = 0; i < n && M > 0; i++) {
		if (nums[i] < 0) {
			nums[i] = -nums[i];
			M--;
		}
	}
	// If a negative sign still exists, the last number becomes negative 
	if (M) {
		for (int i = n - M; i < n; i++) {
			nums[i] = -nums[i];
		} 
	} 
	// Sum 
	for (int i = 0; i < n; i++) {
		res += nums[i];
	}
	cout << res << endl;
	return 0;
} 

Question J: psionic transmission

Time limit: 1.0s memory limit: 256.0MB total score of this question: 25 points
[title background]
In the game "StarCraft II", the high-level Templar, as an important AOE unit of the star spirit, is in
It plays an important role in the middle and later stages of the game. Its skill "psionic storm" can consume a lot of psionic pairs
The enemy in an area inflicts devastating damage. Often used against human biochemical forces and Zerg
Low blood units such as Hydra and dragon.
[problem description]
You control n high-ranking Templars, marked 1,2,..., n for convenience. Every high-ranking Templar
A certain amount of psionics is required to fight. Each person has a psionic value a i, which indicates how many psionics they have (a i)
Non negative indicates that the high-level Templar has a i more psionic power than in the best state, and a i negative indicates this
A high-level Templar also needs − a i psionics to reach the best combat state). Now the system gives
Your high-level Templar has an ability to transmit psionics. Each time you can choose one i ∈ [2,n − 1], if
a i ≥ 0, then the high-level Templars on both sides, i − 1 and i + 1, will
i the high-ranking Templar draws a and i psionic powers here; If a i < 0, the high-level Templars on both sides,
That is, the two high-level Templars i − 1 and i + 1 will give the high-level Templar i − a i some psionic powers. shape
In terms of formula, a I − 1 + = a I, a i + 1 + = a I, a I − = 2a i.
Psionics are very efficient combat tools, but they are also very dangerous and unstable. A high-level temple
It's not good for a warrior to have too many or too few psionics. Define the instability of a group of high-level Templars as
max n
I = 1 | a | I |, please make this group of high-level templars you control through an unlimited number of transfer psionic operations
Minimum instability.
[input format]
This question contains several groups of questions. The first line of input contains a positive integer T, which indicates the number of query groups.
Next, enter each set of queries in turn.
The first line of each query contains a positive integer n, indicating the number of high-level Templars.
The next line contains n numbers a 1, a 2,..., a n.
Question J: psionic transmission 15
Group B of the 10th Blue Bridge Cup software provincial competition C/C + + University
[output format]
Output T line. An integer in each line represents the answers of each group of questions in turn.
[sample input]
3
3
5 -2 3
4
0 0 0 0
3
1 2 3
[sample output]
3
0
3
[example description]
For the first set of questions:
a 1 = 3, a 2 = 2, a 3 = 1 after transmitting to high-level Templar 2. The answer is 3.
For the second set of questions:
This group of high-level Templars has psionics that can make them reach their best combat state.
[sample input]
3
4
-1 -2 -3 7
4
2 3 4 -8
5
-1 -1 6 -1 -1
[sample output]
5
7
4
[sample input]
See document 3 in.
[sample output]
See document 3 ans.
[data scale and agreement]
For all evaluation cases, T ≤ 3, 3 ≤ n ≤ 300000, | a i | ≤ 10 9.
During the evaluation, 25 evaluation cases will be used to test your program. The limitations of each evaluation case are as follows:
Evaluation case number n |a i | special properties
1 = 3 ≤ 1000 none
2,3 ≤ 5 ≤ 1000 none
4,5,6,7 ≤ 10 ≤ 1000 none
8,9,10 ≤ 20 ≤ 1000 none
11 ≤ 100 ≤ 10 9 all a i non negative
12,13,14 ≤ 100 ≤ 10 9 none
15,16 ≤ 500 ≤ 10 9 none
17,18,19 ≤ 5000 ≤ 10 9 none
20 ≤ 5000 ≤ 10 9 all a i non negative
21 ≤ 100000 ≤ 10 9 all a i non negative
22,23 ≤ 100000 ≤ 10 9 none
24,25 ≤ 300000 ≤ 10 9 none
Note: this question has a large amount of input. Please use the fast reading method.

This question is a little big... Simply put, given a set of numbers, our goal is to minimize the number with the largest absolute value through two operations:

1. If a[i] > 0 and a[i - 1] or a[i+1] is less than 0, we can lend a[i] to i-1 elements and i+1 elements, and a[i] will become - a[i].

2. If a[i] < 0 and a[i - 1] or a[i+1] is greater than 0, we can lend a[i-1] and a[i+1] abs(a[i]) to the I element respectively, and then the value of the I element becomes - a[i], that is, a positive number (a[i] itself is less than 0), and a[i - 1] and a[i+1] need to subtract abs(a[i]).

We consider several situations:

1. All numbers are positive or negative, that is, all numbers have the same sign. In this case, you can't borrow it because it doesn't meet the operation requirements. Therefore, in this case, you can find the number with the largest absolute value in the array.

2. For a[i], if a[i] is a positive number and a[i - 1] and a[i + 1] have at least one negative number, then our goal is to reduce the absolute value of the negative number with the largest absolute value. At this time, if the other side is a positive number, we need to consider whether a new positive number with a larger absolute value will be generated after the operation. For example, there are three numbers: 5 - 6, If we change the middle 5 according to the above operation 1: 10 - 5 - 1, the maximum absolute value becomes 10, compared with 6 before, obviously not. If the three numbers are like this: 1, 5 - 7, then we can transform according to operation 1: 6 - 5 - 2. The maximum absolute value is reduced from 7 to 6, which is feasible. So what are the transformation conditions? Assuming that a[i - 1] is a positive number and a[i + 1] is a negative number, the condition can be written as: a[i - 1] + a[i] < ABS (a[i + 1]). If both a[i - 1] and a[i + 1] are negative numbers, operation 1 transformation can be performed when one of the absolute values on both sides is greater than a[i].

3. When a[i] is a negative number, if a[i - 1] is a negative number and a[i+1] is a positive number, then ensure that a[i+1] > abs(a[i] + a[i-1]), operation 2 transformation can be carried out. If both sides are positive numbers, operation 2 transformation can be carried out as long as the value of one side is greater than abs(a[i]). Finally, the code is given:

#include <cstdio>
#include <cmath>
#include <iostream>
using namespace std;

const int MAXN = 300010;
int nums[MAXN]; 

// Judge whether a and b have different signs 
bool judgeYi(int a, int b) {
	return a > 0 && b < 0 || a < 0 && b > 0;
} 

int main() {
	int T, n;
	cin >> T;
	while (T--) {
		cin >> n;
		// Flag whether negative and positive numbers appear 
		bool hasNe = false, hasPo = false;
		int res = 0;
		for (int i = 0; i < n; i++) {
			scanf("%d", &nums[i]);
			if (nums[i] < 0) {
				hasNe = true;
			} else if (nums[i] > 0) {
				hasPo = true;
			}
		}
		// If there are both positive and negative numbers in the array, judge whether operation 1 and operation 2 can be carried out 
		if (hasNe && hasPo) {
			bool canNext;
			do {
				canNext = false;
				for (int i = 1; i < n - 1; i++) {
					// Num [i] is different from num [I-1] or num [i + 1] 
					if (judgeYi(nums[i], nums[i-1]) || judgeYi(nums[i], nums[i+1])) {
						if (nums[i] > 0) {
							// nums[i-1] and nums[i+1] are different signs,
							// if and else here can be combined. For clarity of logic, they are written separately 
							if (judgeYi(nums[i-1], nums[i+1])) {
								if ((nums[i-1] > 0 && abs(nums[i+1]) > nums[i-1] + nums[i]) || 
									(nums[i+1] > 0 && abs(nums[i-1]) > nums[i+1] + nums[i])) {
									nums[i+1] += nums[i];
									nums[i-1] += nums[i];
									nums[i] = -nums[i];
									canNext = true;
								}
							} else { // nums[i-1] and nums[i+1] have the same sign, both < 0 
								if (abs(nums[i-1]) > nums[i] || abs(nums[i+1]) > nums[i]) {
									nums[i+1] += nums[i];
									nums[i-1] += nums[i];
									nums[i] = -nums[i];
									canNext = true;
								} 
							} 
						} else if (nums[i] < 0) {
							// Num [I-1] and num [i + 1] are different signs 
							if (judgeYi(nums[i-1], nums[i+1])) {
								if ((nums[i-1] > 0 && nums[i-1] > abs(nums[i+1] + nums[i])) || 
									(nums[i+1] > 0 && nums[i+1] > abs(nums[i-1] + nums[i]))) {
									nums[i+1] += nums[i];
									nums[i-1] += nums[i];
									nums[i] = -nums[i];
									canNext = true;
								}
							} else { // nums[i-1] and nums[i+1] are the same number, both > 0 
								if (nums[i-1] > abs(nums[i]) || nums[i+1] > abs(nums[i])) {
									nums[i+1] += nums[i];
									nums[i-1] += nums[i];
									nums[i] = -nums[i];
									canNext = true;
								} 
							} 
						}
					} 
				}
			} while (canNext);
		}
		int t;
		// Find the maximum absolute value 
		for (int i = 0; i < n; i++) {
			res = max(res, abs(nums[i]));
		}
		cout << res << endl;
	}
	
	return 0;
}

Well, I'll write it here for the time being. Generally speaking, there are still some difficulties, especially in the examination room environment. Unless you really have experienced hundreds of battles, you will still be a little nervous, and there are many problems. Therefore, to really achieve high scores, you need to have good psychological quality in addition to excellent strength.

The above explanation is only a personal idea and does not guarantee its correctness. If it is helpful to you, you might as well give a praise and support. If there is anything wrong in the blog, please give more advice.

Thanks for watching...

Topics: Algorithm