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

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

第1题:数组指定部分逆序重放

将一个数组中的前k项按逆序重新存放。例如,将数组8,6,5,4,1前3项逆序重放得到5,6,8,4,1。

时间限制:1000

内存限制:65536
输入

输入为两行: 第一行两个整数,以空格分隔,分别为数组元素的个数n(1 < n < 100)以及指定的k(1 <= k <= n)。 第二行是n个整数,每两个整数之间用空格分隔。
输出

输出为一行:输出按题目要求逆序后数组的整数,每两个整数之间用空格分隔。
样例输入

5 3

8 6 5 4 1
样例输出

5 6 8 4 1

以下是使用C语言编写的将数组指定部分逆序重放的程序:

c 复制代码
#include <stdio.h>

void reverseArray(int arr[], int start, int end) {
    while (start < end) {
        int temp = arr[start];
        arr[start] = arr[end];
        arr[end] = temp;
        start++;
        end--;
    }
}

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

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

    reverseArray(arr, 0, k - 1);

    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    return 0;
}

程序首先定义了一个函数reverseArray,用于将数组中指定部分进行逆序。函数接受一个整数数组arr、一个起始索引start和一个结束索引end作为参数。使用双指针的方式,不断交换起始和结束索引对应的元素,直到两个指针相遇为止,完成逆序操作。

接下来,程序使用scanf函数从标准输入读取数组元素的个数n和指定的k值。

然后,定义一个大小为n的整数数组arr,并使用循环从标准输入读取数组的元素。

调用reverseArray函数,将数组arr的前k项进行逆序操作。

最后,使用循环将逆序后的数组arr的元素依次输出到标准输出,并在每两个元素之间添加一个空格。

例如,如果输入为5 38 6 5 4 1,则程序将将数组的前3项8 6 5进行逆序操作,得到5 6 8 4 1,然后将逆序后的数组输出到标准输出。

第2题:序列排序

对于给定的正整数序列,按照每个数的各位数和从大到小排序,各位数和相同的按照本身大小排序,大的在前,小的在后。

时间限制:1000

内存限制:65536
输入

第一行1个整数n,表示序列的大小。( 0 < n ≤ 1000) 第二行n个正整数,表示序列的每个数,每个数不大于100000000。
输出

输出按照题目要求排序后的序列
样例输入

6

17 26 9 13 88 10
样例输出

88 9 26 17 13 10

以下是使用C语言编写的对正整数序列按照各位数和排序的程序:

c 复制代码
#include <stdio.h>

int calculateDigitSum(int num) {
    int sum = 0;
    while (num != 0) {
        sum += num % 10;
        num /= 10;
    }
    return sum;
}

void swap(int* a, int* b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

void sortSequence(int arr[], int size) {
    for (int i = 0; i < size - 1; i++) {
        for (int j = 0; j < size - i - 1; j++) {
            int sum1 = calculateDigitSum(arr[j]);
            int sum2 = calculateDigitSum(arr[j + 1]);
            if (sum1 < sum2 || (sum1 == sum2 && arr[j] < arr[j + 1])) {
                swap(&arr[j], &arr[j + 1]);
            }
        }
    }
}

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

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

    sortSequence(arr, n);

    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");

    return 0;
}

程序首先定义了一个函数calculateDigitSum,用于计算一个正整数的各位数和。函数接受一个整数num作为参数,通过循环将num除以10并取余数的方式,逐位将余数加到sum变量上,然后将num除以10,直到num等于0。最后,返回sum作为各位数和。

接下来,定义了一个辅助函数swap,用于交换两个整数的值。函数接受两个整型指针ab作为参数,通过引用传递的方式交换两个指针所指向的整数值。

然后,定义了一个函数sortSequence,用于对给定的序列按照题目要求进行排序。函数接受一个整数数组arr和数组的大小size作为参数。使用两层循环进行冒泡排序,每一轮比较相邻的两个元素的各位数和和本身大小,并根据题目要求进行交换。

main函数中,首先使用scanf函数从标准输入读取序列的大小n

然后,定义一个大小为n的整数数组arr,并使用循环从标准输入读取序列的每个数。

调用sortSequence函数,将数组arr按照题目要求进行排序。

最后,使用循环将排序后的数组arr的元素依次输出到标准输出,并在每两个元素之间添加一个空格。

例如,如果输入为617 26 9 13 88 10,则程序将对序列进行排序,最终输出为88 9 26 17 13 10

第3题:内部元素之和

输入一个整数矩阵,计算位于矩阵内部的元素之和。所谓矩阵内部的元素,不在第一行和最后一行的元素以及第一列和最后一列的元素。

时间限制:1000

内存限制:65536
输入

第一行分别为矩阵的行数m和列数n(m < 100,n < 100),两者之间以一个空格分开。 接下来输入的m行数据中,每行包含n个整数(每个数大于等于0,小于1000),整数之间以一个空格分开。
输出

输出对应矩阵的内部元素和
样例输入

3 3

3 4 1

3 7 1

2 0 1
样例输出

7

以下是使用C语言编写的计算矩阵内部元素之和的程序:

c 复制代码
#include <stdio.h>

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

    int matrix[m][n];
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            scanf("%d", &matrix[i][j]);
        }
    }

    int sum = 0;
    for (int i = 1; i < m - 1; i++) {
        for (int j = 1; j < n - 1; j++) {
            sum += matrix[i][j];
        }
    }

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

    return 0;
}

程序首先使用scanf函数从标准输入读取矩阵的行数m和列数n

然后,定义一个大小为mn列的整数矩阵matrix,并使用两层循环从标准输入读取矩阵的每个元素。

接下来,定义一个变量sum,用于存储矩阵内部元素之和。

使用两层循环遍历矩阵内部的元素,即从第二行到倒数第二行,从第二列到倒数第二列的元素,并将每个元素的值累加到sum中。

最后,使用printf函数将变量sum的值输出到标准输出。

例如,如果输入为3 3和以下矩阵:

3 4 1
3 7 1
2 0 1

则程序将计算矩阵内部元素之和,即7,并将其输出到标准输出。

第4题:谁考了第k名

在一次考试中,每个学生的成绩都不相同,现知道了每个学生的学号和成绩,求考第k名学生的学号和成绩。

时间限制:1000

内存限制:65536
输入

第一行有两个整数,分别是学生的人数n(1≤n≤100),和求第k名学生的k(1≤k≤n)。 其后有n行数据,每行包括一个学号(整数)和一个成绩(浮点数),中间用一个空格分隔。
输出

输出第k名学生的学号和成绩,中间用空格分隔。(注:请用%g输出成绩)
样例输入

5 3

90788001 67.8

90788002 90.3

90788003 61

90788004 68.4

90788005 73.9
样例输出

90788004 68.4

以下是使用C语言编写的求第k名学生学号和成绩的程序:

c 复制代码
#include <stdio.h>

typedef struct {
    int id;
    float score;
} Student;

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

    Student students[n];
    for (int i = 0; i < n; i++) {
        scanf("%d %f", &students[i].id, &students[i].score);
    }

    // 使用冒泡排序按成绩从高到低排序
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (students[j].score < students[j + 1].score) {
                Student temp = students[j];
                students[j] = students[j + 1];
                students[j + 1] = temp;
            }
        }
    }

    printf("%d %.1f\n", students[k - 1].id, students[k - 1].score);

    return 0;
}

程序首先使用scanf函数从标准输入读取学生的人数n和求第k名学生的k

然后,定义一个结构体Student来表示每个学生的学号和成绩。

接下来,定义一个大小为nStudent类型数组students,并使用循环从标准输入读取每个学生的学号和成绩。

使用冒泡排序将学生按照成绩从高到低进行排序。

最后,使用printf函数将第k名学生的学号和成绩输出到标准输出。

例如,如果输入为5 3和以下学生数据:

90788001 67.8
90788002 90.3
90788003 61
90788004 68.4
90788005 73.9

则程序将对学生按照成绩进行排序,并输出第3名学生的学号和成绩,即90788004 68.4

第5题:话题焦点人物

微博提供了一种便捷的交流平台。一条微博中,可以提及其它用户。例如Lee发出一条微博为:"期末考试顺利 @Kim @Neo",则Lee提及了Kim和Neo两位用户。

我们收集了N(1 < N < 10000)条微博,并已将其中的用户名提取出来,用小于等于100的正整数表示。

通过分析这些数据,我们希望发现大家的话题焦点人物,即被提及最多的人(题目保证这样的人有且只有一个),并找出那些提及它的人。

时间限制:1000

内存限制:65536
输入

输入共两部分: 第一部分是微博数量N,1 < N < 10000。 第二部分是N条微博,每条微博占一行,表示为: 发送者序号a,提及人数k(0 < = k < = 20),然后是k个被提及者序号b1,b2...bk; 其中a和b1,b2...bk均为大于0小于等于100的整数。相邻两个整数之间用单个空格分隔。
输出

输出分两行: 第一行是被提及最多的人的序号; 第二行是提及它的人的序号,从小到大输出,相邻两个数之间用单个空格分隔。同一个序号只输出一次。
样例输入

5

1 2 3 4

1 0

90 3 1 2 4

4 2 3 2

2 1 3
样例输出

3

1 2 4

以下是使用C语言编写的找到话题焦点人物及提及它的人的程序:

c 复制代码
#include <stdio.h>

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

    int mentions[101] = {0};  // 用于记录每个用户被提及的次数,下标表示用户序号
    int mentionedBy[101] = {0};  // 用于记录每个用户提及话题焦点人物的次数,下标表示用户序号

    for (int i = 0; i < N; i++) {
        int sender, count;
        scanf("%d %d", &sender, &count);

        mentions[sender]++;  // 发送者被提及的次数加1

        for (int j = 0; j < count; j++) {
            int mentioned;
            scanf("%d", &mentioned);
            mentionedBy[mentioned]++;  // 被提及者提及话题焦点人物的次数加1
        }
    }

    int maxMentions = -1;  // 最大提及次数
    int focusPerson = -1;  // 话题焦点人物序号

    for (int i = 1; i <= 100; i++) {
        if (mentionedBy[i] > maxMentions) {
            maxMentions = mentionedBy[i];
            focusPerson = i;
        }
    }

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

    for (int i = 1; i <= 100; i++) {
        if (mentions[i] == focusPerson) {
            printf("%d ", i);
        }
    }

    printf("\n");

    return 0;
}

程序首先使用scanf函数从标准输入读取微博的数量N

然后,定义两个大小为101的整数数组mentionsmentionedBy,分别用于记录每个用户被提及的次数和提及话题焦点人物的次数。数组下标表示用户序号。

接下来,使用循环依次读取每条微博的信息。对于每条微博,首先读取发送者的序号和被提及的人数。然后,将发送者的被提及次数加1,并使用另一个循环读取被提及者的序号,并将其提及话题焦点人物的次数加1。

接下来,使用两个循环分别找到被提及最多的人(即提及次数最多的人)和提及它的人。

最后,使用printf函数将话题焦点人物的序号输出到标准输出,并使用另一个循环将提及它的人的序号按照从小到大的顺序输出到标准输出。

例如,如果输入为5和以下微博数据:

1 2 3 4
1 0
90 3 1 2 4
4 2 3 2
2 1 3

则程序将分析微博数据,找到被提及最多的人为3,并输出到标准输出。接着,找到提及它的人为124,并按照从小到大的顺序输出到标准输出,即1 2 4

相关推荐
Charles Ray3 分钟前
C++学习笔记 —— 内存分配 new
c++·笔记·学习
重生之我在20年代敲代码3 分钟前
strncpy函数的使用和模拟实现
c语言·开发语言·c++·经验分享·笔记
2401_858286113 小时前
52.【C语言】 字符函数和字符串函数(strcat函数)
c语言·开发语言
jiao000015 小时前
数据结构——队列
c语言·数据结构·算法
铁匠匠匠5 小时前
从零开始学数据结构系列之第六章《排序简介》
c语言·数据结构·经验分享·笔记·学习·开源·课程设计
C-SDN花园GGbond5 小时前
【探索数据结构与算法】插入排序:原理、实现与分析(图文详解)
c语言·开发语言·数据结构·排序算法
迷迭所归处6 小时前
C++ —— 关于vector
开发语言·c++·算法
CV工程师小林6 小时前
【算法】BFS 系列之边权为 1 的最短路问题
数据结构·c++·算法·leetcode·宽度优先
Navigator_Z7 小时前
数据结构C //线性表(链表)ADT结构及相关函数
c语言·数据结构·算法·链表
white__ice7 小时前
2024.9.19
c++