March 2021 C/C++ (Level 4) real test analysis#中国电子学院#National Youth Software Programming Level Examination

insert image description here

Question 1: Alcoholic

Santo just won a bet with the landlord for a large living room in New Clondike. Today, he came to this large living room to admire his prize. The landlord put out a row of bottles on the bar. The bottles are filled with different volumes of wine. To Santo's delight, the wine in the bottle all tasted different. The landlord said: "You can drink as much wine as you want, but once you open the bottle, you must drink it. After drinking a bottle, put it back in its original place. And one more important thing, you must start from the left. Drink in order from right to left, and don’t exceed three bottles in a row, or it will bring you bad luck.” Now poor Santo is standing in front of the bar and thinking hard, which bottles should he drink to drink the most? Please Help him figure out which bottle number he should be drinking because thinking makes him uneasy.
Time limit: 2000
Memory limit: 131072
Input
The first line is an integer N, and there are N wine bottles. N<=700 is followed by N lines, and the numbers in line I+1 represent the volume of wine in bottle I.
Output
A number, the maximum total volume of wine drunk. Follow the above rules so that at least one of the three consecutive bottles is full.
Sample input
6
6
10
13
9
8
1
Sample output
33

To solve this problem, we can use dynamic programming to find the maximum total volume of wine to drink.

We can define two arrays dpand dpFullwhere dp[i]represents ithe maximum total volume of wine drunk from the previous bottles and dpFull[i]represents ithe maximum total volume of wine drunk from the previous bottles and ithe last bottle of the previous bottles is full of.

According to the title rules, we can get the recurrence relation:

(1) If the first ibottle is not drunk, then dp[i] = dp[i-1].

(2) If the ith bottle is drunk, the previous bottle cannot be drunk, ie dp[i] = dp[i-2] + volume[i].

(3) If the first two bottles are drunk, the first three bottles cannot be drunk consecutively, ie dp[i] = dpFull[i-3] + volume[i].

For dpFullarrays, there are the following recurrence relations:

(1) If the first ibottle is not drunk, then dpFull[i] = dpFull[i-1].

(2) If the ith bottle is drunk, the previous bottle cannot be drunk, ie dpFull[i] = dp[i-2] + volume[i].

Note that in the initial case, when there is only one wine bottle, ie dp[1] = volume[1]and dpFull[1] = volume[1].

The following is the problem-solving code written in C language:

#include <stdio.h>

int max(int a, int b) {
    
    
    return (a > b) ? a : b;
}

int main() {
    
    
    int N;
    scanf("%d", &N);

    int volume[701];
    int dp[701] = {
    
    0};
    int dpFull[701] = {
    
    0};

    for (int i = 1; i <= N; i++) {
    
    
        scanf("%d", &volume[i]);
    }

    dp[1] = volume[1];
    dpFull[1] = volume[1];

    for (int i = 2; i <= N; i++) {
    
    
        dp[i] = max(dp[i - 1], max(dp[i - 2] + volume[i], dpFull[i - 3] + volume[i]));
        dpFull[i] = max(dpFull[i - 1], dp[i - 2] + volume[i]);
    }

    printf("%d\n", dp[N]);

    return 0;
}

In the above code, we first define a helper function maxto return the larger of two numbers.

Then, we define an integer array volumeto store the volume of each wine bottle. At the same time, we define two dynamic programming arrays dpand dpFull, which are used to calculate the maximum total volume of wine drunk.

Next, we use a loop to read the input bottle volume and store it in volumethe array.

Then, we use two loops to calculate the values ​​of the dpand dpFullarrays according to the recurrence relation and the initial situation.

Finally, we output dp[N], i.e. the maximum total volume of wine drunk.

Compiling and running the above code resolves the issue. You can use a C compiler to save the code as .ca file, then compile and run the file to get the results.

Question 2: Restart the system

Xiao Ming helps manage a computing system that processes data. There are N tasks to be processed, and these tasks need to be completed in order, that is, the number of each completed task must be greater than the number of the previous completed task, and a single task cannot be decomposed Finish. The computing system runs a strange protection program, which limits the amount of data that the system can currently process cannot exceed the amount of data processed by the last task completed. Rebooting the system immediately restores it to maximum performance (initially the system has maximum performance, maximum performance is greater than the amount of data of any pending tasks). Xiao Ming has the right to restart the system once (or not use it), can you help him calculate the maximum number of tasks he can complete? Time limit:
1000
Memory limit: 65536
Enter
the first line: N (2 <= N <= 1000) The second line of the number of tasks to be processed: N integers, the data volume
output
of each task The output only includes one line, and this line contains only one integer, indicating the maximum number of tasks that can be completed.
Sample input
10
1 5 4 3 2 10 9 8 7 6
Sample output
9
prompt
Recall the longest ascending subsequence problem

To solve this problem, we can use dynamic programming to find the maximum number of tasks that can be completed.

We can define an array dpwhere dp[i]represents ithe length of the longest ascending subsequence ending with task .

According to the title rules, we can get the recurrence relation:

If ithe data volume of the th task is greater than the data volume of any previous completed task, dp[i] = max(dp[j] + 1)the jvalue range of is [0, i-1], and volume[i] > volume[j].

Note that initially, when there is only one task, ie dp[1] = 1.

Finally, we traverse the entire dparray and find the largest value, which is the maximum number of tasks that can be completed.

The following is the problem-solving code written in C language:

#include <stdio.h>

int max(int a, int b) {
    
    
    return (a > b) ? a : b;
}

int main() {
    
    
    int N;
    scanf("%d", &N);

    int volume[1001];
    int dp[1001] = {
    
    0};

    for (int i = 1; i <= N; i++) {
    
    
        scanf("%d", &volume[i]);
    }

    dp[1] = 1;

    for (int i = 2; i <= N; i++) {
    
    
        for (int j = 1; j <= i - 1; j++) {
    
    
            if (volume[i] > volume[j]) {
    
    
                dp[i] = max(dp[i], dp[j] + 1);
            }
        }
    }

    int maxTasks = 0;
    for (int i = 1; i <= N; i++) {
    
    
        maxTasks = max(maxTasks, dp[i]);
    }

    printf("%d\n", maxTasks);

    return 0;
}

In the above code, we first define a helper function maxto return the larger of two numbers.

Then, we define an array of integers volumeto store the amount of data for each task.

Next, we use a loop to read the input amount of task data and store it in volumean array.

Then, we use two nested loops to calculate dpthe value of the array, and update the length of the longest ascending subsequence according to the recurrence relation.

Finally, we traverse the entire dparray and find the largest value, which is the maximum number of tasks that can be completed.

Compiling and running the above code resolves the issue. You can use a C compiler to save the code as .ca file, then compile and run the file to get the results.

Question 3: Naruto's Shadow Clone

In the world of Naruto, being unpredictable to the enemy is very important. A move our protagonist Uzumaki Naruto possesses - the multiple shadow clone technique - is a good example of this.
The shadow clone is created by the chakra energy of Naruto's body, the more chakra used, the stronger the shadow clone created.
According to different combat situations, Naruto can choose to create shadow clones of various strengths, some are used for feint attacks, and some are used for fatal blows.
So here comes the question, assuming that Naruto's Chakra energy is M, and the number of his shadow clones is N, how many different distribution methods (expressed in K) are there when making shadow clones? (Shadow clones can be assigned to 0 Point chakra energy)
time limit: 1000
memory limit: 65536
input
The first line is the number of test data t (0 <= t <= 20). Each of the following lines contains two integers M and N, separated by spaces. 1 <= M, N <= 10.
Output
For each set of input data M and N, use one line to output the corresponding K.
Sample input
1
7 3
Sample output
8

To solve this problem, we can use dynamic programming to calculate different allocation methods.

We can define a two-dimensional array dp, where represents the number of different allocation methods to create shadow clones dp[i][j]when the Chakra energy is .ij

According to the title rules, we can get the recurrence relation:

(1) At that j = 0time , that is, there is no shadow clone to be produced, so no matter how much chakra energy is, there is only one distribution method, that is, not to distribute any chakra to the shadow clone, ie dp[i][0] = 1.

(2) At that i = 0time , that is, the Chakra energy is 0, and no shadow clone can be created, so no matter how many shadow clones need to be created, there is no distribution method, ie dp[0][j] = 0.

(3) For other cases, we can traverse jthe chakra energy of the th shadow clone from 0 to , and assign it to the th shadow clone, and then calculate the remaining chakra energy distribution to the previous shadow clone. The sum of the number of methods, that is , where the range of values ​​is .iji - kj-1dp[i][j] = dp[i][j] + dp[i - k][j - 1]k[0, i]

Finally, we traverse dp[M][N], that is, the chakra energy is M, the number of different distribution methods in the case of making Nshadow clones.

The following is the problem-solving code written in C language:

#include <stdio.h>

int main() {
    
    
    int t;
    scanf("%d", &t);

    while (t--) {
    
    
        int M, N;
        scanf("%d %d", &M, &N);

        int dp[11][11] = {
    
    0};

        for (int j = 0; j <= N; j++) {
    
    
            dp[0][j] = 0;
        }

        for (int i = 0; i <= M; i++) {
    
    
            dp[i][0] = 1;
        }

        for (int i = 1; i <= M; i++) {
    
    
            for (int j = 1; j <= N; j++) {
    
    
                for (int k = 0; k <= i; k++) {
    
    
                    dp[i][j] += dp[i - k][j - 1];
                }
            }
        }

        printf("%d\n", dp[M][N]);
    }

    return 0;
}

In the above code, we first read the number of test data t.

Then, we use a whileloop to process each set of test data.

In each set of test data, we first read Mthe sum N, which is the number of chakra energy and shadow clones.

Next, we define a two-dimensional array dpfor counting the number of different allocation methods.

dpThen, we initialize the array according to the recurrence relation .

Then, we use three nested loops to calculate dpthe value of the array, and update the number of different allocation methods according to the recurrence relationship.

Finally, we output dp[M][N], i.e. the corresponding number of different allocation methods.

Compiling and running the above code resolves the issue. You can use a C compiler to save the code as .ca file, then compile and run the file to get the results.

Question 4: Conquering Pokemon

Pokemon is a story about the adventures of Ash and his partner Pikachu.
One day, Xiaozhi and Pikachu came to the elf hunting ground, where there are many precious wild Pokemon. Xiaozhi also wants to tame some of the elves. However, wild elves are not so easy to tame. For each wild elf, Xiao Zhi may need to use many poke balls to subdue it, and in the process of subduing, the wild elves will also cause certain damage to Pikachu (thereby reducing Pikachu's physical strength). When Pikachu's physical strength is less than or equal to 0, Xiaozhi must end the hunt (because he needs to heal Pikachu's injuries), and wild elves that make Pikachu's physical strength less than or equal to 0 will not be subdued by Xiaozhi. When Ash's Poké Balls run out, the hunt comes to an end.
Let's assume that Xiaozhi has two choices when he encounters a wild elf: subdue it, or leave it. If Xiaozhi chooses to subdue it, he will definitely throw a Poké Ball that can subdue the Pokémon, and Pikachu will definitely receive corresponding damage; if he chooses to leave it, then Xiaozhi will not lose the Poké Ball, and neither will Pikachu physical strength.
Xiaozhi has two goals: the main goal is to subdue as many wild elves as possible; if the number of elves that can be subdued is the same, Xiaozhi hopes that Pikachu will suffer less damage (greater remaining stamina), because they will continue to fight. adventure.
Now the number of Pokéballs of Ash and Pikachu's initial physical strength are known, the number of Pokéballs each Pokémon needs to be subdued and the amount of damage it will cause to Pikachu during the subduing process are known. May I ask, how does Xiaozhi choose which elves to conquer to achieve his goal?
Time limit: 1000
Memory limit: 65536
Input
The first line of the input data contains three integers: N(0 < N < 1000), M(0 < M < 500), K (0 < K < 100), respectively represent the number of Ash’s Poké Balls, Pikachu’s initial physical strength, and the number of wild Pokémon. In the following K lines, each line represents a wild elf, including two integers: the number of poke balls needed to tame the elf, and the damage caused to Pikachu during the taming process.
output
The output is one line, containing two integers: C, R, respectively indicating that at most C elves can be subdued, and Pikachu's remaining physical strength is at most R when subduing C elves.
Sample input
Sample input 1:
10 100 5
7 10
2 40
2 50
1 20
4 20
Sample input 2:
10 100 5
8 110
12 10
20 10
5 200
1 110 Sample
output
Sample output 1:
3 30
samples Example output 2:
0 100
Prompt
For example input 1: Xiaozhi chooses: (7,10) (2,40) (1,20) In this way, Xiaozhi subdued 3 elves in total, and Pikachu received 70 points of damage. The remaining 100-70=30 physical strength. So output 3 30 For sample input 2: Xiaozhi can't subdue a single elf, and Pikachu will not receive any damage, so output 0 100
to run the test
Console: Clean up the console

The idea of ​​solving the problem is as follows:

(1) First, we need to use dynamic programming to solve this problem. We define a two-dimensional array dp[N+1][M+1], where represents the maximum number of elves that can be subdued when the remaining physical strength is , dp[i][j]using the previous ielf ball .j

(2) Initialize dpthe array: For dp[0][j](that is, use 0 elf balls), no matter how much remaining physical strength is, the elf cannot be subdued, so it is initialized to 0. For dp[i][0](that is, the remaining physical strength is 0), no matter how many poke balls are used, the adventure cannot be continued, so it is initialized to 0.

(3) Update dpthe value of the array according to the recursive relationship: for each elf, we have two choices: take it in or leave it. If we choose to subdue it, we need to consider two factors: the number of poke balls used and the damage caused to Pikachu. We iterate over all possible poke ball numbers and damages, and update dp[i][j]the value of max( dp[i-1][j], dp[i-1][j-damage] + balls), where ballsand damagerepresent ithe number of poke balls needed by the th pokemon and the damage caused to Pikachu, respectively.

(4) Finally, we traverse the entire dparray to find the value with the largest number of captured elves max_capturedand the corresponding maximum remaining physical strength max_remain_hp.

(5) Output max_capturedand max_remain_hp.

The following is the C language problem-solving code according to the requirements of the topic:

#include <stdio.h>

int max(int a, int b) {
    
    
    return (a > b) ? a : b;
}

int main() {
    
    
    int N, M, K;
    scanf("%d %d %d", &N, &M, &K);

    int dp[N + 1][M + 1];
    int balls[K], damage[K];

    for (int i = 0; i < K; i++) {
    
    
        scanf("%d %d", &balls[i], &damage[i]);
    }

    for (int i = 0; i <= N; i++) {
    
    
        for (int j = 0; j <= M; j++) {
    
    
            if (i == 0 || j == 0) {
    
    
                dp[i][j] = 0;
            } else {
    
    
                dp[i][j] = dp[i - 1][j];
                if (j >= damage[i - 1]) {
    
    
                    dp[i][j] = max(dp[i][j], dp[i - 1][j - damage[i - 1]] + balls[i - 1]);
                }
            }
        }
    }

    int max_captured = 0;
    int max_remain_hp = M;
    for (int i = 0; i <= N; i++) {
    
    
        for (int j = 0; j <= M; j++) {
    
    
            if (dp[i][j] > max_captured) {
    
    
                max_captured = dp[i][j];
                max_remain_hp = M - j;
            }
        }
    }

    printf("%d %d\n", max_captured, max_remain_hp);

    return 0;
}

Here we use a maxfunction to return the larger of two numbers.

Then, we defined a two-dimensional array dpto store the intermediate results, and defined two arrays ballsand damageto store the number of poke balls and the damage value of each wild pokemon.

Next, we use two nested loops to calculate dpthe value of the array, updating dp[i][j]the value of according to the recurrence relation.

Finally, we traverse the entire dparray to find the maximum value and the corresponding index, that is, the maximum number of elves and the maximum value of the remaining physical strength of Pikachu that can be subdued. Then output these two values.

Run the above code to get the result. You can save the code as .ca file, then compile and run the file to get the result.

Guess you like

Origin blog.csdn.net/gozhuyinglong/article/details/132381602