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

在这里插入图片描述

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

第1题:铺砖

对于一个2行N列的走道。现在用12,22的砖去铺满。问有多少种不同的方式。
时间限制:3000
内存限制:131072
输入
整个测试有多组数据,请做到文件底结束。每行给出一个数字N,0 <= n <= 250
输出
如题
样例输入
2
8
12
100
200
样例输出
3
171
2731
845100400152152934331135470251
1071292029505993517027974728227441735014801995855195223534251

下面是一个使用C语言实现的解决方案,可以计算铺砖的不同方式数量:

#include <stdio.h>

#define MAX_N 251

typedef long long ll;

ll dp[MAX_N];

// 动态规划求解铺砖的不同方式数量
void calculate_ways() {
    
    
    dp[0] = 1;
    dp[1] = 1;
    dp[2] = 3;

    for (int i = 3; i < MAX_N; i++) {
    
    
        dp[i] = dp[i-1] + 2 * dp[i-2];
    }
}

int main() {
    
    
    calculate_ways();

    int N;
    while (scanf("%d", &N) != EOF) {
    
    
        printf("%lld\n", dp[N]);
    }

    return 0;
}

这个实现中,我们使用动态规划的思想来计算铺砖的不同方式数量。首先,我们定义一个全局数组dp,用于存储不同长度走道的铺砖方式数量。然后,我们通过递推关系式dp[i] = dp[i-1] + 2 * dp[i-2]来计算不同长度走道的铺砖方式数量。

main函数中,我们首先调用calculate_ways函数,计算出所有长度走道的铺砖方式数量。然后,我们循环读取输入的走道长度N,并输出对应的铺砖方式数量dp[N]

注意:在实际编写和运行代码时,请确保输入数据的格式和范围符合题目要求,并进行必要的错误处理。此外,题目给出的时间限制较短,因此可以采用动态规划预计算的方式,在实际查询时直接输出结果,而不需要每次都重新计算。

第2题:吃糖果2

现有n(50 > n > 0)个糖果,每天只能吃2个或者3个,请计算共有多少种不同的吃法吃完糖果。
时间限制:1000
内存限制:65536
输入
输入的每一行包括一组测试数据,即为糖果数n。最后一行为0,表示测试结束。
输出
每一行输出对应一行输入的结果,即为吃法的数目。
样例输入
1
2
3
4
12
0
样例输出
0
1
1
1
12

下面是一个使用C语言实现的解决方案,可以计算吃糖果的不同吃法数量:

#include <stdio.h>

int count_eating_ways(int n) {
    
    
    if (n < 2) {
    
    
        return 0;
    }

    int dp[n + 1];
    dp[0] = 0;
    dp[1] = 0;
    dp[2] = 1;
    dp[3] = 1;

    for (int i = 4; i <= n; i++) {
    
    
        dp[i] = dp[i - 2] + dp[i - 3];
    }

    return dp[n];
}

int main() {
    
    
    int n;

    while (scanf("%d", &n) == 1 && n != 0) {
    
    
        int ways = count_eating_ways(n);
        printf("%d\n", ways);
    }

    return 0;
}

这个实现中,我们定义了一个辅助函数count_eating_ways,用于计算吃糖果的不同吃法数量。在函数中,我们使用动态规划的思想来计算,定义一个数组dp,其中dp[i]表示吃i个糖果的不同吃法数量。初始时,我们将dp[0]dp[1]设为0,dp[2]dp[3]设为1。然后,我们通过递推关系式dp[i] = dp[i - 2] + dp[i - 3]来计算吃i个糖果的不同吃法数量。

main函数中,我们循环读取输入的糖果数量n,并调用count_eating_ways函数计算对应的吃法数量。最后,我们输出吃法数量。

注意:在实际编写和运行代码时,请确保输入数据的格式和范围符合题目要求,并进行必要的错误处理。

第3题:扩号匹配问题

在某个字符串(长度不超过100)中有左括号、右括号和大小写字母;规定(与常见的算数式子一样)任何一个左括号都从内到外与在它右边且距离最近的右括号匹配。写一个程序,找到无法匹配的左括号和右括号,输出原来字符串,并在下一行标出不能匹配的括号。不能匹配的左括号用"$“标注,不能匹配的右括号用”?“标注.
时间限制:3000
内存限制:65536
输入
输入包括多组数据,每组数据一行,包含一个字符串,只包含左右括号和大小写字母,字符串长度不超过100
输出
对每组输出数据,输出两行,第一行包含原始输入字符,第二行由”$“,”?“和空格组成,”$“和”?"表示与之对应的左括号和右括号不能匹配。
样例输入
((ABCD(x)
)(rttyy())sss)(
样例输出
((ABCD(x)
$$
)(rttyy())sss)(
?           ?$

下面是一个使用C语言实现的解决方案,可以找到无法匹配的左括号和右括号,并输出标记后的字符串:

#include <stdio.h>
#include <string.h>

#define MAX_LENGTH 100

void match_parentheses(char* str) {
    
    
    int len = strlen(str);
    int mismatch[len];
    memset(mismatch, 0, sizeof(mismatch));

    int stack[MAX_LENGTH];
    int top = -1;

    for (int i = 0; i < len; i++) {
    
    
        if (str[i] == '(') {
    
    
            stack[++top] = i;
        } else if (str[i] == ')') {
    
    
            if (top == -1) {
    
    
                mismatch[i] = 1;
            } else {
    
    
                top--;
            }
        }
    }

    while (top != -1) {
    
    
        mismatch[stack[top--]] = 1;
    }

    for (int i = 0; i < len; i++) {
    
    
        if (mismatch[i] == 1) {
    
    
            str[i] = '$';
        } else if (str[i] == ')') {
    
    
            str[i] = '?';
        }
    }
}

int main() {
    
    
    char str[MAX_LENGTH];

    while (fgets(str, MAX_LENGTH, stdin) != NULL) {
    
    
        int len = strlen(str);
        if (str[len - 1] == '\n') {
    
    
            str[len - 1] = '\0';
        }

        match_parentheses(str);

        printf("%s\n", str);

        for (int i = 0; i < len; i++) {
    
    
            if (str[i] == '$' || str[i] == '?') {
    
    
                printf("%c", str[i]);
            } else {
    
    
                printf(" ");
            }
        }
        printf("\n");
    }

    return 0;
}

这个实现中,我们定义了一个辅助函数match_parentheses,用于找到无法匹配的左括号和右括号,并将其标记为'$''?'。函数中,我们使用一个栈来辅助匹配括号,遍历字符串,当遇到左括号时,将其索引入栈;当遇到右括号时,如果栈为空,则说明没有与之匹配的左括号,将当前右括号标记为无法匹配;否则,将栈顶的左括号出栈,表示匹配成功。最后,将剩余未匹配的左括号标记为无法匹配。

main函数中,我们循环读取输入的字符串,并调用match_parentheses函数对其进行处理。然后,我们先输出原始字符串,再输出标记后的字符串,其中无法匹配的左括号用'$'表示,无法匹配的右括号用'?'表示。

注意:在实际编写和运行代码时,请确保输入数据的格式和范围符合题目要求,并进行必要的错误处理。

第4题:质数的和与积

两个质数的和是S,它们的积最大是多少?
时间限制:10000
内存限制:65536
输入
一个不大于10000的正整数S,为两个质数的和。
输出
一个整数,为两个质数的最大乘积。数据保证有解。
样例输入
50
样例输出
589

下面是一个使用C语言实现的解决方案,可以找到两个质数的和为给定值S时,它们的最大乘积:

#include <stdio.h>

int is_prime(int n) {
    
    
    if (n < 2) {
    
    
        return 0;
    }

    for (int i = 2; i * i <= n; i++) {
    
    
        if (n % i == 0) {
    
    
            return 0;
        }
    }

    return 1;
}

int find_max_product(int S) {
    
    
    int max_product = 0;

    for (int i = 2; i <= S / 2; i++) {
    
    
        if (is_prime(i) && is_prime(S - i)) {
    
    
            int product = i * (S - i);
            if (product > max_product) {
    
    
                max_product = product;
            }
        }
    }

    return max_product;
}

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

    int max_product = find_max_product(S);
    printf("%d\n", max_product);

    return 0;
}

这个实现中,我们定义了两个辅助函数。is_prime函数用于判断一个数是否为质数。在函数中,我们首先判断小于2的数不是质数。然后,从2开始遍历到该数的平方根,如果存在能整除该数的因子,说明该数不是质数,否则是质数。

find_max_product函数用于找到两个质数的和为给定值S时,它们的最大乘积。在函数中,我们从2开始遍历到S的一半,对于每个数i,判断它和S - i是否都是质数。如果是质数,则计算它们的乘积,并与当前的最大乘积比较,更新最大乘积。

main函数中,我们读取输入的S,并调用find_max_product函数找到最大乘积。然后,我们输出最大乘积。

注意:在实际编写和运行代码时,请确保输入数据的格式和范围符合题目要求,并进行必要的错误处理。此外,题目保证有解,因此不需要额外处理无解的情况。

第5题:因子问题

任给两个正整数N、M,求一个最小的正整数a,使得a和(M-a)都是N的因子。
时间限制:10000
内存限制:65536
输入
包括两个整数N、M。N不超过1,000,000。
输出
输出一个整数a,表示结果。如果某个案例中满足条件的正整数不存在,则在对应行输出-1
样例输入
35 10
样例输出
5

下面是一个使用C语言实现的解决方案,可以找到满足条件的最小正整数a:

#include <stdio.h>

int find_smallest_factor(int N, int M) {
    
    
    for (int a = 1; a <= N; a++) {
    
    
        if (N % a == 0 && (M - a) % N == 0) {
    
    
            return a;
        }
    }
    return -1;
}

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

    int smallest_factor = find_smallest_factor(N, M);
    printf("%d\n", smallest_factor);

    return 0;
}

这个实现中,我们定义了一个辅助函数find_smallest_factor,用于找到满足条件的最小正整数a。在函数中,我们从1开始遍历到N,对于每个数a,判断是否同时满足两个条件:N能整除a,且(M - a)能整除N。如果满足条件,则返回a作为最小正整数;如果遍历完所有可能的a都不满足条件,则返回-1。

main函数中,我们读取输入的N和M,并调用find_smallest_factor函数找到最小正整数a。然后,我们输出a。

注意:在实际编写和运行代码时,请确保输入数据的格式和范围符合题目要求,并进行必要的错误处理。

猜你喜欢

转载自blog.csdn.net/gozhuyinglong/article/details/132700751
今日推荐