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

news2024/7/6 19:16:14

在这里插入图片描述

第1题:最小新整数

给定一个十进制正整数n(0 < n < 1000000000),每个数位上数字均不为0。n的位数为m。 现在从m位中删除k位(0<k < m),求生成的新整数最小为多少? 例如: n = 9128456, k = 2, 则生成的新整数最小为12456
时间限制:1000
内存限制:65536
输入
第一行t, 表示有t组数据; 接下来t行,每一行表示一组测试数据,每组测试数据包含两个数字n, k。
输出
t行,每行一个数字,表示从n中删除k位后得到的最小整数。
样例输入
2
9128456 2
1444 3
样例输出
12456
1

下面是一个使用C语言编写的解决方案,根据给定的要求计算生成的新整数的最小值:

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

// 函数用于删除字符串中的指定位置的字符
void removeChar(char* str, int index) {
    int len = strlen(str);
    for (int i = index; i < len - 1; i++) {
        str[i] = str[i + 1];
    }
    str[len - 1] = '\0';
}

// 函数用于计算从n中删除k位后得到的最小整数
void calculateMinInteger(char* n, int k) {
    int len = strlen(n);
    int removed = 0; // 记录已删除的位数

    while (k > 0 && removed < len) {
        int minIndex = 0; // 记录当前最小位的索引
        for (int i = 1; i <= k; i++) {
            if (n[i] < n[minIndex]) {
                minIndex = i;
            }
        }

        removeChar(n, minIndex); // 删除当前最小位
        k -= minIndex; // 更新剩余需要删除的位数
        removed++; // 更新已删除的位数
    }

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

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

    for (int i = 0; i < t; i++) {
        char n[20];
        int k;
        scanf("%s %d", n, &k);
        calculateMinInteger(n, k);
    }

    return 0;
}

这个解决方案首先定义了两个辅助函数:removeChar() 用于删除字符串中的指定位置的字符,calculateMinInteger() 用于计算从n中删除k位后得到的最小整数。

main() 函数中,首先读取要处理的数据组数 t。接下来,使用一个循环读取每组测试数据,并调用 calculateMinInteger() 函数进行计算和输出结果。

这个解决方案使用了一个字符数组来存储输入的数字 n。在 calculateMinInteger() 函数中,通过循环选择当前最小的位,并删除该位,直到删除的位数 k 为 0 或已删除的位数达到字符串的长度。

第2题:求逆序对数

对于一个长度为N的整数序列A,满足i < j 且 Ai > Aj.的数对(i,j)称为整数序列A的一个逆序
请求出整数序列A的所有逆序对个数
时间限制:500
内存限制:65536
输入
输入包含多组测试数据,每组测试数据有两行 第一行为整数N(1 <= N <= 20000),当输入0时结束 第二行为N个整数,表示长为N的整数序列
输出
每组数据对应一行,输出逆序对的个数
样例输入
5
1 2 3 4 5
5
5 4 3 2 1
1
1
0
样例输出
0
10
0

下面是一个使用C语言编写的解决方案,用于计算整数序列的逆序对个数:

#include <stdio.h>
#include <stdlib.h>

// 归并排序并计算逆序对的个数
long long mergeSort(int arr[], int temp[], int left, int right) {
    long long count = 0;

    if (left < right) {
        int mid = (left + right) / 2;

        // 分别对左右两个子数组进行归并排序并计算逆序对的个数
        count += mergeSort(arr, temp, left, mid);
        count += mergeSort(arr, temp, mid + 1, right);

        // 合并两个有序子数组并计算逆序对的个数
        int i = left;
        int j = mid + 1;
        int k = left;

        while (i <= mid && j <= right) {
            if (arr[i] <= arr[j]) {
                temp[k++] = arr[i++];
            } else {
                temp[k++] = arr[j++];
                count += mid - i + 1; // 添加逆序对的个数
            }
        }

        while (i <= mid) {
            temp[k++] = arr[i++];
        }

        while (j <= right) {
            temp[k++] = arr[j++];
        }

        // 将合并后的结果拷贝回原数组
        for (int m = left; m <= right; m++) {
            arr[m] = temp[m];
        }
    }

    return count;
}

int main() {
    int N;

    while (scanf("%d", &N) == 1 && N != 0) {
        int arr[N];
        int temp[N];

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

        long long count = mergeSort(arr, temp, 0, N - 1);
        printf("%lld\n", count);
    }

    return 0;
}

这个解决方案使用归并排序的思想来计算逆序对的个数。它首先读取输入的整数序列和序列的长度,并定义一个临时数组用于归并排序的过程。

mergeSort() 函数中,使用递归的方式将原始数组划分为较小的子数组,并分别对左右两个子数组进行归并排序。在合并两个有序子数组的过程中,通过比较元素大小来计算逆序对的个数,并将合并结果存储在临时数组中。最后,将临时数组的内容拷贝回原数组。

main() 函数中,使用一个循环读取多组测试数据。每组数据包括整数序列的长度和具体的序列内容。通过调用 mergeSort() 函数计算逆序对的个数,并输出结果。

第3题:密室逃脱

小Y喜欢玩密室逃脱,每次游戏开始时,小Y会进入一个密室,她需要按照顺序解开各个隐藏线索才能成功逃脱密室。小Y非常聪明,解开线索对她来说并不难,但是她有一点懒,她希望在通关过程中移动次数最少。请你帮小Y计算她至少要移动多少次才能成功通关。
密室是m行n列的格子矩阵,小Y从左上角(1,1)进入密室,密室中有三种格子:
墙,以数字0标记
路,以数字1标记
隐藏线索处,以数字( > 1)标记, 代表该线索的难度
小Y需要按照难度递增的顺序解开各个线索,逃脱密室。
时间限制:1000
内存限制:65536
输入
第一行是一个整数 T,表示输入包含 T 组数据,分别是不同的游戏中小Y所处的密室。 对于每组数据,第一行包括两个整数:m(1 <= m <= 100)、n(1 <= n <= 100)。 接下来 m 行,每行有n个数字,第 i 行的第 j 个数字表示密室中第 i 行第 j 列的格子的类型。 题目保证进入密室处(1,1)不是墙壁,线索的难度都不相同。
输出
对于每组数据,你需要输出一个整数,表示小Y在这个密室中至少要移动多少次才能成功通关。 如果小Y不可能解开所有线索,输出-1.
样例输入
2
3 3
1 3 2
1 0 4
10 6 5
3 3
1 3 2
0 0 0
10 6 5
样例输出
8
-1
提示
样例解释:由于需要按难度顺序解开线索,在第一组数据中,小Y第一次移动到3时不能解密,在完成2之后需要回到3.最后小Y解开10时,她成功通关。

下面是一个使用C语言编写的解决方案,用于计算小Y至少需要移动多少次才能成功通关:

#include <stdio.h>
#include <stdlib.h>

#define MAX_SIZE 100

// 定义坐标结构体
typedef struct {
    int x;
    int y;
} Coordinate;

// 定义队列结构体
typedef struct {
    Coordinate items[MAX_SIZE];
    int front;
    int rear;
} Queue;

// 初始化队列
void initQueue(Queue* queue) {
    queue->front = 0;
    queue->rear = 0;
}

// 判断队列是否为空
int isQueueEmpty(Queue* queue) {
    return queue->front == queue->rear;
}

// 入队
void enqueue(Queue* queue, Coordinate item) {
    queue->items[queue->rear] = item;
    queue->rear = (queue->rear + 1) % MAX_SIZE;
}

// 出队
Coordinate dequeue(Queue* queue) {
    Coordinate item = queue->items[queue->front];
    queue->front = (queue->front + 1) % MAX_SIZE;
    return item;
}

// 判断坐标是否有效
int isValidCoordinate(int m, int n, int x, int y) {
    return (x >= 0 && x < m && y >= 0 && y < n);
}

// 计算小Y至少需要移动多少次才能成功通关
int minimumMoves(int maze[][MAX_SIZE], int m, int n) {
    Coordinate start = {0, 0}; // 起始位置
    Coordinate end = {m - 1, n - 1}; // 终点位置

    int visited[MAX_SIZE][MAX_SIZE] = {0}; // 记录每个格子是否访问过
    int distance[MAX_SIZE][MAX_SIZE]; // 记录起始位置到每个格子的最短距离

    Queue queue;
    initQueue(&queue);
    enqueue(&queue, start);
    visited[start.x][start.y] = 1;
    distance[start.x][start.y] = 0;

    int dx[4] = {-1, 0, 1, 0}; // 上下左右四个方向
    int dy[4] = {0, 1, 0, -1};

    while (!isQueueEmpty(&queue)) {
        Coordinate current = dequeue(&queue);

        // 到达终点,返回最短距离
        if (current.x == end.x && current.y == end.y) {
            return distance[current.x][current.y];
        }

        // 遍历当前位置的四个邻居
        for (int i = 0; i < 4; i++) {
            int nextX = current.x + dx[i];
            int nextY = current.y + dy[i];

            // 如果邻居坐标有效且未访问过,进行处理
            if (isValidCoordinate(m, n, nextX, nextY) && !visited[nextX][nextY]) {
                visited[nextX][nextY] = 1;
                enqueue(&queue, (Coordinate){nextX, nextY});
                distance[nextX][nextY] = distance[current.x][current.y] + 1;
            }
        }
    }

    // 无法解开所有线索,返回-1
    return -1;
}

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

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

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

        int minMoves = minimumMoves(maze, m, n);
        printf("%d\n", minMoves);
    }

    return 0;
}

这个解决方案使用了广度优先搜索(BFS)算法来计算小Y至少需要移动多少次才能成功通关。它使用队列来进行广度优先遍历,并记录起始位置到每个格子的最短距离。

minimumMoves() 函数中,首先定义起始位置和终点位置,并初始化队列、访问数组和距离数组。然后,使用广度优先搜索算法遍历迷宫,直到到达终点位置或队列为空。在遍历过程中,检查当前位置的四个邻居,如果邻居坐标有效且未访问过,则将邻居坐标入队,并更新访问数组和距离数组。

最后,如果成功到达终点位置,则返回最短距离;否则,返回-1,表示无法解开所有线索。

main() 函数中,根据输入的测试数据,依次读取迷宫的大小和格子的类型,并调用 minimumMoves() 函数计算小Y至少需要移动的次数,并输出结果。

第4题:红与黑

有一间长方形的房子,地上铺了红色、黑色两种颜色的正方形瓷砖。你站在其中一块黑色的瓷砖上,只能向相邻的黑色瓷砖移动。请写一个程序,计算你总共能够到达多少块黑色的瓷砖。
时间限制:1000
内存限制:65536
输入
包括多个数据集合。每个数据集合的第一行是两个整数W和H,分别表示x方向和y方向瓷砖的数量。W和H都不超过20。在接下来的H行中,每行包括W个字符。每个字符表示一块瓷砖的颜色,规则如下 1)‘.’:黑色的瓷砖; 2)‘#’:白色的瓷砖; 3)‘@’:黑色的瓷砖,并且你站在这块瓷砖上。该字符在每个数据集合中唯一出现一次。 当在一行中读入的是两个零时,表示输入结束。
输出
对每个数据集合,分别输出一行,显示你从初始位置出发能到达的瓷砖数(记数时包括初始位置的瓷砖)。
样例输入
6 9
…#.
…#





#@…#
.#…#.
0 0
样例输出
45

下面是一个使用C语言编写的解决方案,用于计算你从初始位置出发能够到达的黑色瓷砖数:

#include <stdio.h>

#define MAX_SIZE 20

// 定义坐标结构体
typedef struct {
    int x;
    int y;
} Coordinate;

// 计算你能够到达的黑色瓷砖数
int countBlackTiles(char tiles[][MAX_SIZE], int W, int H, Coordinate start) {
    int count = 0; // 统计黑色瓷砖数

    // 定义四个方向的偏移量
    int dx[4] = {-1, 1, 0, 0};
    int dy[4] = {0, 0, -1, 1};

    // 创建一个栈来保存待访问的黑色瓷砖坐标
    Coordinate stack[MAX_SIZE * MAX_SIZE];
    int top = 0;

    // 将初始位置标记为已访问,并将其入栈
    int visited[MAX_SIZE][MAX_SIZE] = {0};
    visited[start.x][start.y] = 1;
    stack[top++] = start;

    while (top > 0) {
        Coordinate current = stack[--top];
        count++;

        // 遍历当前位置的四个相邻位置
        for (int i = 0; i < 4; i++) {
            int nextX = current.x + dx[i];
            int nextY = current.y + dy[i];

            // 如果相邻位置有效且为黑色瓷砖且未访问过,将其标记为已访问并入栈
            if (nextX >= 0 && nextX < H && nextY >= 0 && nextY < W &&
                tiles[nextX][nextY] == '.' && !visited[nextX][nextY]) {
                visited[nextX][nextY] = 1;
                stack[top++] = (Coordinate){nextX, nextY};
            }
        }
    }

    return count;
}

int main() {
    while (1) {
        int W, H;
        scanf("%d %d", &W, &H);

        if (W == 0 && H == 0) {
            break;
        }

        char tiles[MAX_SIZE][MAX_SIZE];
        Coordinate start;

        for (int i = 0; i < H; i++) {
            scanf("%s", tiles[i]);
            for (int j = 0; j < W; j++) {
                if (tiles[i][j] == '@') {
                    start.x = i;
                    start.y = j;
                }
            }
        }

        int blackTiles = countBlackTiles(tiles, W, H, start);
        printf("%d\n", blackTiles);
    }

    return 0;
}

这个解决方案使用了深度优先搜索(DFS)算法来计算你能够到达的黑色瓷砖数。它使用栈来进行深度优先遍历,并使用一个二维数组 visited 来记录每个瓷砖是否已经访问过。

countBlackTiles() 函数中,首先定义四个方向的偏移量,并创建一个栈和一个 visited 数组。将初始位置标记为已访问,并将其入栈。

然后,使用深度优先搜索算法遍历瓷砖,直到栈为空。在遍历过程中,从栈中弹出一个瓷砖坐标,并将其计入黑色瓷砖数。然后,遍历该瓷砖的四个相邻位置,如果相邻位置有效且为黑色瓷砖且未访问过,则将其标记为已访问并入栈。

最后,返回计数结果。

main() 函数中,首先读取输入的瓷砖布局和初始位置。然后,调用 countBlackTiles() 函数计算你能够到达的黑色瓷砖数,并输出结果。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/942468.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

校园自动气象站丨感知气象、了解自然

校园自动气象站安装在校园的一个角落中&#xff0c;守护着在学校中师生&#xff0c;时刻观测着校园周围的气象变化&#xff0c;拥有高度集成、低功耗、安装即用、可以用于教学的气象仪器。 校园气象站中配置了多种气象设备&#xff0c;包括但不限于温度传感器、湿度传感器、风…

YOLOv5算法改进(8)— 替换主干网络之MobileNetV3

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。MobileNetV3是由Google团队在2019年提出的一种卷积神经网络结构&#xff0c;其目标是在保持高性能的同时减少计算延时。MobileNetV3相比于前一版本&#xff08;MobileNetV2&#xff09;在性能上有明显的提升。根据原论文&a…

证明arcsinx+arccosx=π/2,并且为什么arcsinx-arccosx=π/2不成立

下面我们先直接用代数式来证明一下&#xff1a; 设 y 1 arcsin ⁡ x &#xff0c; y 2 arccos ⁡ x &#xff0c;求 y 1 y 2 由于 x sin ⁡ y 1 cos ⁡ y 2 &#xff0c;而 cos ⁡ y 2 sin ⁡ ( y 2 π 2 ) 那么就得到 y 1 y 2 π 2 &#xff0c;即 y 1 − y 2 π 2 …

ViewPager+ Fragment结合的setUserVisibleHint()调用时机

最近的项目使用到了ViewPager Fragment的模式&#xff0c;要求在每次Fragment获取显示的时候来刷新数据&#xff0c;该项目下ViewPager有5个子fragment&#xff0c;在onCreateView及fragment的**setUserVisibleHint&#xff08;bool isVisibleToUser)**中的isVisibleToUser为t…

Jmeter(二十七):BeanShell PostProcessor跨线程全局变量使用

在性能测试中&#xff0c;两个相关联的接口不一定都在同一个线程组&#xff0c;遇见这种情况时&#xff0c;我们要进行跨线程组传参&#xff0c;此处用登录和查询配送单两个请求举例&#xff1b; 1、登录请求中配置json提取器&#xff0c;将接口返回的token保存在变量中&#…

Linux 指令心法(二)`cd` 更改当前目录

文章目录 命令的概述和用途命令的用法命令行选项和参数的详细说明命令的示例命令的注意事项或提示 命令的概述和用途 cd 是 “Change Directory” 的缩写。这是一个 shell 内建命令&#xff0c;用于在 Linux 和 Unix 系统中改变当前工作目录。通过使用 cd 命令&#xff0c;用户…

Python小知识 - Python中的多线程

Python中的多线程 线程是进程中的一个执行单元&#xff0c;是轻量级的进程。一个进程可以创建多个线程&#xff0c;线程之间共享进程的资源&#xff0c;比如内存、文件句柄等。 在Python中&#xff0c;使用threading模块实现线程。 下面的代码创建了两个线程&#xff0c;一个输…

【数学建模】清风数模正课5 相关性分析

相关系数 相关性分析的关键是计算相关系数&#xff0c;在本节课中将会介绍两种常用的相关系数&#xff1a;皮尔逊相关系数&#xff08;Pearson&#xff09;和斯皮尔曼相关系数&#xff08;Spearman&#xff09;。 它们可以用来衡量两个变量间相关性的大小&#xff0c;对于不同…

后端面试话术集锦第三篇:spring cloud 面试话术

🚗后端面试集锦目录 💖后端面试话术集锦第一篇:spring面试话术💖 💖后端面试话术集锦第二篇:spring boot面试话术💖 💖后端面试话术集锦第三篇:spring cloud面试话术💖 💖后端面试话术集锦第四篇:ElasticSearch面试话术💖 💖后端面试话术集锦第五篇:r…

面试现场表现:展示你的编程能力和沟通技巧

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

【力扣】55、跳跃游戏

var canJump function(nums){let cover 0;for(let i0;i<nums.length;i){if(i<cover){cover Math.max(nums[i]i,cover);if(cover >nums.length-1){return true;}}}}

春秋云镜 CVE-2018-7448

春秋云镜 CVE-2018-7448 CMS Made Simple 2.1.6 RCE 靶标介绍 CMS Made Simple 2.1.6版本存在代码注入漏洞&#xff0c;可以通过 timezone 参数执行任意代码。 启动场景 漏洞利用 1、目的文件夹选择/var/www/html/cms 2、next到第四步&#xff0c;数据库名&#xff1a;cms…

2023-8-29 有向图的拓扑排序

题目链接&#xff1a;有向图的拓扑排序 #include <cstring> #include <iostream> #include <algorithm>using namespace std;const int N 100010;int n, m; int h[N], e[N], ne[N], idx;int q[N], d[N];void add(int a, int b) {e[idx] b, ne[idx] h[a]…

Android11.0 Launcher3定制化功能之抽屉式(双层)app列表排序功能实现

1.概述 在11.0的系统开发中,在定制Launcher3的开发中,对于抽屉式即双层桌面的workspace的app列表排序的功能,也是常有的需求,把常用的app图标放在前面,其他的可以放在列表后面做个整体的排序,这就需要了解app列表排序的流程,然后根据需求来实现功能 如图: 2.Launche…

面试中的代码写作:如何撰写清晰、高效的示例代码

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

代码随想录算法训练营之JAVA|第四十二天|70. 爬楼梯

今天是第 天刷leetcode&#xff0c;立个flag&#xff0c;打卡60天&#xff0c;如果做不到&#xff0c;完成一件评论区点赞最高的挑战。 算法挑战链接 70. 爬楼梯https://leetcode.cn/problems/climbing-stairs/ 第一想法 这是一个动态规划的入门题目&#xff0c;在看完完全背…

Flutter(九)Flutter动画和自定义组件

目录 1.动画简介2.动画实现和监听3. 自定义路由切换动画4. Hero动画5.交织动画6.动画切换7.Flutter预置的动画过渡组件自定义组件1.简介2.组合组件3.CustomPaint 和 RenderObject 1.动画简介 Animation、Curve、Controller、Tween这四个角色&#xff0c;它们一起配合来完成一个…

操作系统真题

操作系统真题 考点前驱图真题分页存储管理索引文件结构分段存储管理进程的状态进程的同步和互斥 考点 考试只会考察选择题 前驱图真题 c 这是常考题型 b 分页存储管理 将程序分页 --逻辑地址 将内存分为页框&#xff08;物理块&#xff09; --物理地址 程序页的大小和页框的大小…

ros2官方文档(基于humble版本)学习笔记

ros2官方文档&#xff08;基于humble版本&#xff09;学习笔记&#xff08;一&#xff09; 一、安装ROS2二、按教程学习1.CLI 工具配置环境 由于市面上专门讲ROS2开发的书籍不多&#xff0c;近期看完了《ROS机器人开发实践》其中大部分内容还是基于ROS1写的&#xff0c;涉及top…

图像扭曲之波浪扭曲

源码&#xff1a; void wave_sine(cv::Mat& src,cv::Mat& dst,double amplitude,double wavelength) {dst.create(src.rows, src.cols, CV_8UC3);dst.setTo(0);double xAmplitude amplitude;double yAmplitude amplitude;double xWavelength wavelength;double yWa…