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

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

第1题:数字字符求和

请编写一个程序实现以下功能:从一个字符串中,提取出所有的数字字符即0-9,并作为数求和。
时间限制:1000
内存限制:65536
输入
一行字符串,长度不超过100,字符串中不含空格。
输出
字符串中所有数字字符作为数的和
样例输入
Lsd2f02k3ja3sdf223
样例输出
17

以下是解决该问题的C语言代码:

#include 
#include 

int sumDigits(const char* str) {
    int sum = 0;
    int len = strlen(str);

    for (int i = 0; i < len; i++) {
        if (str[i] >= '0' && str[i] <= '9') {
            sum += str[i] - '0';
        }
    }

    return sum;
}

int main() {
    char str[101];
    scanf("%s", str);

    int result = sumDigits(str);
    printf("%d\n", result);

    return 0;
}

你可以将上述代码保存为一个名为 “sum_digits.c” 的文件,并使用C编译器进行编译和运行。在输入字符串后,程序将提取出字符串中的数字字符,并计算它们的和。

在主函数中,我们首先读取输入的字符串,并将其存储在 str 字符数组中。

然后,我们调用 sumDigits 函数来计算字符串中数字字符的和。在该函数中,我们使用一个循环遍历字符串的每个字符。

对于每个字符,我们判断它是否是数字字符。如果是,则将其转换为对应的数字,并将其加到 sum 变量中。

最后,我们在主函数中输出计算得到的和。

请注意,这个解决方案假设输入是有效的,并且字符串中只包含数字字符和非数字字符。如果输入不符合要求,可能会导致输出错误。

第2题:简单密码

Julius Caesar曾经使用过一种很简单的密码。对于明文中的每个字符,将它用它字母表中后5位对应的字符来代替,这样就得到了密文。比如字符A用F来代替。如下是密文和明文中字符的对应关系。 密文 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 明文 V W X Y Z A B C D E F G H I J K L M N O P Q R S T U 你的任务是对给定的密文进行解密得到明文。 你需要注意的是,密文中出现的字母都是大写字母。密文中也包括非字母的字符,对这些字符不用进行解码。
时间限制:1000
内存限制:65536
输入
一行,给出密文,密文不为空,而且其中的字符数不超过200。
输出
输出一行,即密文对应的明文。
样例输入
NS BFW, JAJSYX TK NRUTWYFSHJ FWJ YMJ WJXZQY TK YWNANFQ HFZXJX
样例输出
IN WAR, EVENTS OF IMPORTANCE ARE THE RESULT OF TRIVIAL CAUSES

以下是解决该问题的C语言代码:

#include 
#include 

void decrypt(char *ciphertext) {
    while (*ciphertext != '\0') {
        if (isalpha(*ciphertext)) {
            if (*ciphertext >= 'F')
                *ciphertext -= 5;
            else
                *ciphertext += 21;
        }
        ciphertext++;
    }
}

int main() {
    char ciphertext[201];
    fgets(ciphertext, sizeof(ciphertext), stdin);

    decrypt(ciphertext);

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

    return 0;
}

你可以将上述代码保存为一个名为 “decrypt.c” 的文件,并使用C编译器进行编译和运行。在输入密文后,程序将解密得到明文并输出。

decrypt 函数中,我们使用了一个指针来遍历密文字符串。对于每个字符,我们首先检查它是否是字母。如果是字母,我们进行解密操作。

根据题目要求,我们将字母表中的字符向后移动5位来进行解密。如果字符大于等于 ‘F’,我们将其减去5来得到对应的明文字符。否则,我们将其加上21(26-5)来得到对应的明文字符。

最后,我们在主函数中读取输入的密文,并调用 decrypt 函数进行解密操作。然后,我们输出解密后的明文。

请注意,这个解决方案假设输入是有效的,并且密文中只包含大写字母和非字母字符。如果输入不符合要求,可能会导致输出错误。

第3题:进阶的卡莎

虚空之女·卡莎考入了战斗学院,她的父亲虚空行者·卡萨丁要检查她的考试成绩。已知卡莎一段时间内的成绩序列,请你帮卡萨丁计算卡莎在这段时间内最长的成绩连续上升(相等不算做连续上升)的长度。
例如,给出卡莎的成绩序列是85 90 80 85 90 95 95 80 75 75,其中连续上升序列包括“85 90”和“80 85 90 95”两组,后者是最长的连续上升成绩序列(相等不算做连续上升),应该输出后者的长度4。
时间限制:1000
内存限制:65536
输入
输入的第一行是序列的长度N(1 <= N <= 100)。 第二行给出序列中的N个整数,这些整数的取值范围都在0到100。
输出
最长的成绩连续上升的长度(相等不算做连续上升)。
样例输入
10
85 90 80 85 90 95 95 80 75 75
样例输出
4

以下是解决该问题的C语言代码:

#include 

int longestIncreasingSequence(int grades[], int length) {
    int maxLen = 0;
    int currentLen = 1;

    for (int i = 1; i < length; i++) {
        if (grades[i] > grades[i - 1]) {
            currentLen++;
        } else {
            if (currentLen > maxLen) {
                maxLen = currentLen;
            }
            currentLen = 1;
        }
    }

    if (currentLen > maxLen) {
        maxLen = currentLen;
    }

    return maxLen;
}

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

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

    int result = longestIncreasingSequence(grades, length);
    printf("%d\n", result);

    return 0;
}

你可以将上述代码保存为一个名为 “longest_sequence.c” 的文件,并使用C编译器进行编译和运行。在输入成绩序列后,程序将计算最长的连续上升成绩序列的长度,并输出结果。

longestIncreasingSequence 函数中,我们使用一个循环遍历成绩数组。对于每个成绩,我们检查它是否大于前一个成绩。如果是,则当前连续上升序列的长度加1;否则,我们将当前连续上升序列的长度与最大长度进行比较,并更新最大长度为较大的值,然后将当前连续上升序列的长度重置为1。

最后,我们在主函数中首先读取输入的序列长度,并使用一个循环读取序列中的整数。

然后,我们调用 longestIncreasingSequence 函数来计算最长的连续上升成绩序列的长度。在该函数中,我们传入成绩数组和数组长度作为参数。

最后,我们在主函数中输出计算得到的最长连续上升序列的长度。

请注意,这个解决方案假设输入是有效的,并且成绩序列中的整数取值范围在0到100之间。如果输入不符合要求,可能会导致输出错误。

第4题:合影效果

小云和朋友们去爬香山,为美丽的景色所陶醉,想合影留念。如果他们站成一排,男生全部在左(从拍照者的角度),并按照从矮到高的顺序从左到右排,女生全部在右,并按照从高到矮的顺序从左到右排,请问他们合影的效果是什么样的(所有人的身高都不同)?
时间限制:1000
内存限制:65536
输入
第一行是人数n(2 <= n <= 40,且至少有1个男生和1个女生)。 后面紧跟n行,每行输入一个人的性别(男male或女female)和身高(浮点数,单位米),两个数据之间以空格分隔。
输出
n个浮点数,模拟站好队后,拍照者眼中从左到右每个人的身高。每个浮点数需保留到小数点后2位,相邻两个数之间用单个空格隔开。
样例输入
6
male 1.72
male 1.78
female 1.61
male 1.65
female 1.70
female 1.56
样例输出
1.65 1.72 1.78 1.70 1.61 1.56

以下是解决该问题的C语言代码:

#include 
#include 
#include 

// 定义一个人的结构体
typedef struct {
    char gender[10];
    float height;
} Person;

// 比较函数,用于排序
int compare(const void *a, const void *b) {
    const Person *person1 = (const Person *)a;
    const Person *person2 = (const Person *)b;

    // 如果是男生,按身高从矮到高排序
    if (strcmp(person1->gender, "male") == 0) {
        if (strcmp(person2->gender, "male") == 0) {
            return person1->height - person2->height;
        } else {
            return -1;  // 男生排在前面
        }
    }
    // 如果是女生,按身高从高到矮排序
    else {
        if (strcmp(person2->gender, "female") == 0) {
            return person2->height - person1->height;
        } else {
            return 1;  // 女生排在后面
        }
    }
}

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

    Person *people = (Person *)malloc(n * sizeof(Person));

    // 读取每个人的性别和身高
    for (int i = 0; i < n; i++) {
        char gender[10];
        float height;
        scanf("%s%f", gender, &height);

        strcpy(people[i].gender, gender);
        people[i].height = height;
    }

    // 排序
    qsort(people, n, sizeof(Person), compare);

    // 输出排序后的身高
    for (int i = 0; i < n; i++) {
        printf("%.2f ", people[i].height);
    }
    printf("\n");

    free(people);

    return 0;
}

你可以将上述代码保存为一个名为 “photo_effect.c” 的文件,并使用C编译器进行编译和运行。在输入人数以及每个人的性别和身高后,程序将模拟站好队后,以拍照者眼中从左到右的顺序输出每个人的身高。

首先,我们定义了一个名为 Person 的结构体,用于表示每个人的性别和身高。

然后,我们使用 malloc 动态分配了一个 Person 数组,大小为输入的人数 n

接下来,我们使用一个循环读取每个人的性别和身高,并将其存储在 people 数组中。

然后,我们使用 qsort 函数对 people 数组进行排序,使用自定义的 compare 函数作为比较函数。在比较函数中,我们根据性别和身高进行排序,男生按身高从矮到高排序,女生按身高从高到矮排序。

最后,我们使用一个循环输出排序后的身高。

请注意,这个解决方案假设输入是有效的,并且至少有一个男生和一个女生。如果输入不符合要求,可能会导致输出错误。

第5题:割圆

本题将实现一个简化版的“割圆”游戏。成功点亮所有灯时,联结第一个和最后一个灯称之为“割线”。
n盏灯环形分布,顺序编号为1到n。灯的初始状态为关闭不亮。假设n为7,则第1号灯与第2、7号灯相邻,第2号灯与第1、3号灯相邻,以此类推。
灯的点亮规则如下:
1、输入m个数,每个数为某个灯的编号,可能重复或只是部分编号;
2、m个数中的第1个数所对应的灯,默认点亮;
3、 如果输入数对应灯的左侧或右侧已被点亮,则点亮自身。否则啥也不做;
4、如果所有的灯都已被点亮,则程序结束,m个数中尚未被处理的数将不再处理;
5、输出第1次和最后一次点亮灯的编号;
6、如果m个数处理完毕尚未点亮所有灯,则输出No。
时间限制:1000
内存限制:131072
输入
第一行2个整数n,m,保证3<=n<=1000,1<=m<=10000。 第二行m个数,每个数都在1到n之间,表示输入序列。
输出
如果完成了“割圆”,则输出两个整数,之间用一个空格隔开,否则输出No。
样例输入
7 10
2 3 1 7 5 6 5 4 4 2
样例输出
2 4
提示
第1个数2,直接被点亮; 第2个数3,3与已亮的2相邻,被点亮; 第3个数1,1与已亮的2相邻,被点亮; 第4个数7,7与已亮的1相邻,被点亮; 第5个数5,5与4和6相邻,但4和6都没亮,什么都不做; 第6个数6,6与已亮的7相邻,被点亮; 第7个数5,5与已亮的6相邻,被点亮; 第8个数4,4与已亮的5相邻,被点亮; 此时,所有的数都被点亮,第1个点亮的是2,最后点亮的是4。

以下是解决该问题的C语言代码:

#include 
#include 

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

    bool lights[n + 1];
    for (int i = 1; i <= n; i++) {
        lights[i] = false;
    }

    int firstLit = 0;
    int lastLit = 0;

    for (int i = 0; i < m; i++) {
        int num;
        scanf("%d", &num);

        if (!lights[num]) {
            lights[num] = true;
            if (firstLit == 0) {
                firstLit = num;
            }
            lastLit = num;
        }

        if (i == m - 1 && lastLit != num) {
            printf("No\n");
            return 0;
        }

        if (lights[num % n + 1] || lights[(num - 2 + n) % n + 1]) {
            continue;
        }
    }

    if (firstLit != 0 && lastLit != 0) {
        printf("%d %d\n", firstLit, lastLit);
    } else {
        printf("No\n");
    }

    return 0;
}

你可以将上述代码保存为一个名为 “circle_cut.c” 的文件,并使用C编译器进行编译和运行。在输入灯的数量 n、输入序列长度 m 和每个数对应的灯的编号后,程序将模拟点亮灯的过程,并输出第一次和最后一次点亮的灯的编号。

首先,我们定义了一个布尔数组 lights,用于表示每个灯的状态,初始状态都为关闭。

然后,我们使用一个循环读取输入序列中的每个数 num

如果 num 对应的灯还没有被点亮,我们将其点亮,并更新 firstLitlastLit 的值。

如果 lastLit 与当前的 num 不相等,并且已经处理完输入序列但最后一个数没有被点亮,那么输出 “No”。

如果 num 对应的灯的左侧或右侧已经被点亮,我们继续处理下一个数。

最后,如果 firstLitlastLit 的值都不为0,那么输出第一次和最后一次点亮的灯的编号;否则,输出 “No”。

请注意,这个解决方案假设输入是有效的,并且输入序列中的数都在1到n之间。如果输入不符合要求,可能会导致输出错误。

你可能感兴趣的:(C/C++等级考试历届真题解析,c语言,c++,开发语言,等级考试,电子学会)