2023年09月 C/C++(四级)真题解析#中国电子学会#全国青少年软件编程等级考试

2023年09月 C/C++(四级)真题解析#中国电子学会#全国青少年软件编程等级考试_第1张图片

C/C++编程(1~8级)全部真题・点这里
Python编程(1~6级)全部真题・点这里

第1题:酒鬼

Santo刚刚与房东打赌赢得了一间在New Clondike 的大客厅。今天,他来到这个大客厅欣赏他的奖品。房东摆出了一行瓶子在酒吧上。瓶子里都装有不同体积的酒。令Santo高兴的是,瓶子中的酒都有不同的味道。房东说道:“你可以喝尽可能多的酒,但是一旦打开酒盖你就必须把它喝完,喝完一瓶后把它放回原处。还有一件最重要的事,你必须从左至右依次喝,并且不能连续超过三瓶,不然会给你带来坏运气。”现在可怜的Santo站在酒吧前努力的想着,他到底应该喝哪几瓶才能使喝的酒最多呢?请帮助他找出他应该喝的酒瓶号,因为思考让他感到不安。
时间限制:2000
内存限制:131072
输入
第一行一个整数N,有N个酒瓶。N<=700接下有N行,第I+1行的数字代表酒瓶I中酒的体积。
输出
一个数字,喝的酒的最大总体积。遵守以上规则,使得三个连续瓶子中至少一个瓶子是满的。
样例输入
6
6
10
13
9
8
1
样例输出
33

这个问题可以使用动态规划来解决。我们可以定义一个数组dp,其中dp[i]表示从第1瓶到第i瓶中可以喝的最大总体积。然后,我们可以使用以下递推关系来计算dp[i]的值:

  • 如果只有一瓶酒(i = 1),则dp[i]等于该酒瓶的体积。

  • 如果有两瓶酒(i = 2),则dp[i]等于前两瓶酒瓶体积的最大值。

  • 如果有三瓶或更多的酒(i >= 3),则有两种情况:

    • 情况一:喝第i瓶酒,那么前两瓶酒中至少有一瓶是满的。此时,dp[i]等于第i瓶酒的体积加上dp[i-2]

    • 情况二:不喝第i瓶酒,那么前两瓶酒中至少有两瓶是满的。此时,dp[i]等于dp[i-1]

最后,我们返回dp[N]作为喝的酒的最大总体积。以下是使用C语言编写的解决方案:

#include 

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

int maxDrinkingVolume(int volumes[], int N) {
    int dp[702];  // dp数组,从0开始
    dp[0] = 0;    // 初始化dp[0]
    dp[1] = volumes[0];  // 只有一瓶酒

    if (N >= 2) {
        dp[2] = max(volumes[0], volumes[1]);  // 有两瓶酒
    }

    for (int i = 3; i <= N; i++) {
        dp[i] = max(volumes[i-1] + dp[i-2], dp[i-1]);  // 递推关系
    }

    return dp[N];
}

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

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

    int result = maxDrinkingVolume(volumes, N);
    printf("%d\n", result);

    return 0;
}

程序首先使用scanf函数从标准输入读取酒瓶的数量N。

然后,使用一个循环从标准输入读取每个酒瓶的体积,并将它们存储在一个名为volumes的数组中。

调用maxDrinkingVolume函数,传递酒瓶体积数组和酒瓶数量作为参数,计算最大的喝酒总体积。

maxDrinkingVolume函数中,定义一个名为dp的数组,用于存储动态规划的结果。

根据递推关系,使用一个循环从3到N,计算dp[i]的值。

最后,返回dp[N]作为喝的酒的最大总体积。

在主函数中,使用printf函数输出计算得到的结果。

例如,如果输入为6,表示有6个酒瓶,然后依次输入6个酒瓶的体积。

程序将计算喝的酒的最大总体积,并输出。

根据给定的数据,喝的酒的最大总体积为33,输出"33"。

第2题:大盗

阿福是一名经验丰富的大盗。趁着月黑风高,阿福打算今晚洗劫一条街上的店铺。
这条街上一共有 N 家店铺,每家店中都有一些现金。阿福事先调查得知,只有当他同时洗劫了两家相邻的店铺时,街上的报警系统才会启动,然后警察就会蜂拥而至。
作为一向谨慎作案的大盗,阿福不愿意冒着被警察追捕的风险行窃。他想知道,在不惊动警察的情况下,他今晚最多可以得到多少现金?
时间限制:1000
内存限制:65536
输入
输入的第一行是一个整数 T (T <= 50) ,表示一共有 T 组数据。 接下来的每组数据,第一行是一个整数 N (1 <= N <= 100, 000) ,表示一共有 N 家店铺。第二行是 N 个被空格分开的正整数,表示每一家店铺中的现金数量。每家店铺中的现金数量均不超过 1000 。
输出
对于每组数据,输出一行。该行包含一个整数,表示阿福在不惊动警察的情况下可以得到的现金数量。
样例输入
2
3
1 8 2
4
10 7 6 14
样例输出
8
24
提示
对于第一组样例,阿福选择第 2 家店铺行窃,获得的现金数量为 8 。 对于第二组样例,阿福选择第 1 和 4 家店铺行窃,获得的现金数量为 10 + 14 = 24 。

以下是使用C语言编写的解决方案:

#include 

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

int maxCash(int cash[], int N) {
    int dp[100002];  // dp数组,从0开始
    dp[0] = 0;    // 初始化dp[0]
    dp[1] = cash[0];  // 只有一家店铺

    if (N >= 2) {
        dp[2] = max(cash[0], cash[1]);  // 有两家店铺
    }

    for (int i = 3; i <= N; i++) {
        dp[i] = max(cash[i-1] + dp[i-2], dp[i-1]);  // 递推关系
    }

    return dp[N];
}

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

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

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

        int result = maxCash(cash, N);
        printf("%d\n", result);
    }

    return 0;
}

程序首先使用scanf函数从标准输入读取数据组数T。

然后,使用一个循环对每组数据进行处理。

在每次循环中,使用scanf函数从标准输入读取店铺数量N。

然后,使用一个循环从标准输入读取每家店铺的现金数量,并将它们存储在一个名为cash的数组中。

调用maxCash函数,传递现金数量数组和店铺数量作为参数,计算阿福可以得到的最大现金数量。

maxCash函数中,定义一个名为dp的数组,用于存储动态规划的结果。

根据递推关系,使用一个循环从3到N,计算dp[i]的值。

最后,返回dp[N]作为阿福可以得到的最大现金数量。

在主函数中,使用printf函数输出计算得到的结果。

例如,如果输入为2,表示有2组数据,然后依次输入每组数据的店铺数量和每家店铺的现金数量。

程序将计算阿福可以得到的最大现金数量,并输出。

根据给定的数据,第一组数据中阿福可以得到的最大现金数量为8,输出"8"。第二组数据中阿福可以得到的最大现金数量为24,输出"24"。

第3题:核电站

一个核电站有N个放核物质的坑,坑排列在一条直线上。如果连续M个坑中放入核物质,则会发生爆炸,于是,在某些坑中可能不放核物质。
任务:对于给定的N和M,求不发生爆炸的放置核物质的方案总数
时间限制:6000
内存限制:131072
输入
只一行,两个正整数N,M( 1 < N < 50,2 ≤ M ≤ 5 )
输出
一个正整数S,表示方案总数。
样例输入
4 3
样例输出
13

以下是使用C语言编写的解决方案:

#include 

long long int countArrangements(int N, int M) {
    long long int dp[51][6] = {0};  // dp数组,从0开始
    dp[0][0] = 1;  // 初始化dp[0][0]

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

    long long int sum = 0;
    for (int j = 0; j <= M; j++) {
        sum += dp[N][j];  // 将所有dp[N][j]的值相加
    }

    return sum;
}

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

    long long int result = countArrangements(N, M);
    printf("%lld\n", result);

    return 0;
}

程序首先使用scanf函数从标准输入读取核电站的坑数量N和连续放置核物质的坑数量M。

调用countArrangements函数,传递坑数量N和连续放置核物质的坑数量M作为参数,计算不发生爆炸的放置核物质的方案总数。

countArrangements函数中,定义一个名为dp的二维数组,用于存储动态规划的结果。

根据递推关系,使用三个嵌套循环,依次计算dp[i][j]的值。

最后,将所有dp[N][j]的值相加,得到方案总数。

在主函数中,使用printf函数输出计算得到的结果。

例如,如果输入为4 3,表示核电站有4个坑,连续放置核物质的坑数量为3。

程序将计算不发生爆炸的放置核物质的方案总数,并输出。

根据给定的数据,不发生爆炸的放置核物质的方案总数为13,输出"13"。

第4题:盒子与小球之二

N个有差别的盒子(1<=N<=20)。你有A个红球和B个蓝球。0 <= A <= 15, 0 <= B <= 15。球除了颜色没有任何区别。你可以将球放进盒子。一个盒子可以同时放进两种球,也可以只放一种,也可以空着。球不必全部放入盒子中。编程计算有多少种放置球的方法。
时间限制:10000
内存限制:131072
输入
就一行,N,A,B,用空格分开
输出
就一行,输出放置方案总数
样例输入
2 1 1
样例输出
9

以下是使用C语言编写的解决方案:

#include 

int countArrangements(int N, int A, int B) {
    int dp[21][16][16] = {0};  // dp数组,从0开始
    dp[0][0][0] = 1;  // 初始化dp[0][0][0]

    for (int i = 1; i <= N; i++) {
        for (int j = 0; j <= A; j++) {
            for (int k = 0; k <= B; k++) {
                for (int x = 0; x <= j; x++) {
                    for (int y = 0; y <= k; y++) {
                        dp[i][j][k] += dp[i - 1][j - x][k - y];  // 递推关系
                    }
                }
            }
        }
    }

    int sum = 0;
    for (int j = 0; j <= A; j++) {
        for (int k = 0; k <= B; k++) {
            sum += dp[N][j][k];  // 将所有dp[N][j][k]的值相加
        }
    }

    return sum;
}

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

    int result = countArrangements(N, A, B);
    printf("%d\n", result);

    return 0;
}

程序首先使用scanf函数从标准输入读取盒子数量N、红球数量A和蓝球数量B。

调用countArrangements函数,传递盒子数量N、红球数量A和蓝球数量B作为参数,计算放置球的方法总数。

countArrangements函数中,定义一个名为dp的三维数组,用于存储动态规划的结果。

根据递推关系,使用五个嵌套循环,依次计算dp[i][j][k]的值。

最后,将所有dp[N][j][k]的值相加,得到放置球的方法总数。

在主函数中,使用printf函数输出计算得到的结果。

例如,如果输入为2 1 1,表示有2个盒子,1个红球和1个蓝球。

程序将计算放置球的方法总数,并输出。

根据给定的数据,放置球的方法总数为9,输出"9"。

你可能感兴趣的:(c语言,c++,等级考试,电子学会)