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

在这里插入图片描述

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

第1题:波兰表达式

波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的波兰表示法为+ 2 3。波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 + 3) * 4的波兰表示法为* + 2 3 4。本题求解波兰表达式的值,其中运算符包括+ - * /四个。
时间限制:1000
内存限制:65536
输入
输入为一行,其中运算符和运算数之间都用空格分隔,运算数是浮点数。
输出
输出为一行,表达式的值。 可直接用printf(“%f\n”, v)输出表达式的值v。
样例输入
* + 11.0 12.0 + 24.0 35.0
样例输出
1357.000000

下面是解决这个问题的C语言代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>#define MAX_SIZE 100// 定义栈结构
typedef struct {int top;double stack[MAX_SIZE];
} Stack;// 初始化栈
void initialize(Stack *s) {s->top = -1;
}// 判断栈是否为空
int isEmpty(Stack *s) {return s->top == -1;
}// 判断栈是否已满
int isFull(Stack *s) {return s->top == MAX_SIZE - 1;
}// 入栈
void push(Stack *s, double value) {if (isFull(s)) {printf("Stack is full. Cannot push element.\n");} else {s->stack[++(s->top)] = value;}
}// 出栈
double pop(Stack *s) {if (isEmpty(s)) {printf("Stack is empty. Cannot pop element.\n");return 0.0;} else {return s->stack[(s->top)--];}
}// 计算波兰表达式的值
double calculatePolishExpression(char *expression) {Stack stack;initialize(&stack);int len = strlen(expression);char *token = strtok(expression, " ");while (token != NULL) {// 如果是运算符,则弹出栈顶的两个元素进行运算,并将结果入栈if (strcmp(token, "+") == 0 || strcmp(token, "-") == 0 ||strcmp(token, "*") == 0 || strcmp(token, "/") == 0) {double operand2 = pop(&stack);double operand1 = pop(&stack);double result = 0.0;if (strcmp(token, "+") == 0) {result = operand1 + operand2;} else if (strcmp(token, "-") == 0) {result = operand1 - operand2;} else if (strcmp(token, "*") == 0) {result = operand1 * operand2;} else if (strcmp(token, "/") == 0) {result = operand1 / operand2;}push(&stack, result);}// 如果是运算数,则将其转换为浮点数并入栈else {double number = atof(token);push(&stack, number);}token = strtok(NULL, " ");}// 返回栈顶的元素,即为表达式的值return pop(&stack);
}int main() {char expression[MAX_SIZE];fgets(expression, MAX_SIZE, stdin);// 删除末尾的换行符expression[strcspn(expression, "\n")] = '\0';double result = calculatePolishExpression(expression);printf("%f\n", result);return 0;
}

该程序首先定义了一个栈的结构体,并实现了栈的相关操作函数。

然后,程序定义了calculatePolishExpression函数,用于计算波兰表达式的值。在函数中,首先创建一个栈,并对其进行初始化。然后,通过遍历表达式中的每个元素,逐个处理。

如果当前元素是运算符,则从栈中弹出栈顶的两个元素,进行相应的运算,并将结果压入栈中。

如果当前元素是运算数,则将其转换为浮点数,并压入栈中。

最后,返回栈顶的元素,即为表达式的值。

main函数中,程序首先读取输入的波兰表达式,并调用calculatePolishExpression函数计算表达式的值。最后,将结果使用printf函数输出。

第2题:括号配对

字符串中可能有三种成对的括号,“( )”、“[ ]”、“{ }”。请判断字符串的括号是否都正确配对。无括号也算正确配对。括号交叉算不正确配对,例如"12{34[78}ab]“就不算正确配对。但是一对括号被包含在另一对括号里面,例如"12{ab[8]}“不影响正确性。
时间限制:1000
内存限制:65536
输入
第一行为整数n(n<40),接下来有n行,每行一个无空格的字符串,长度小于1000。
输出
对每行字符串,如果括号配对,输出"YES”,否则输出"NO”。
样例输入
2
12{ab[8]}
12{34[78}ab]
样例输出
YES
NO

下面是解决这个问题的C语言代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>#define MAX_SIZE 1000// 定义栈结构
typedef struct {int top;char stack[MAX_SIZE];
} Stack;// 初始化栈
void initialize(Stack *s) {s->top = -1;
}// 判断栈是否为空
int isEmpty(Stack *s) {return s->top == -1;
}// 判断栈是否已满
int isFull(Stack *s) {return s->top == MAX_SIZE - 1;
}// 入栈
void push(Stack *s, char value) {if (isFull(s)) {printf("Stack is full. Cannot push element.\n");} else {s->stack[++(s->top)] = value;}
}// 出栈
char pop(Stack *s) {if (isEmpty(s)) {printf("Stack is empty. Cannot pop element.\n");return '\0';} else {return s->stack[(s->top)--];}
}// 判断括号是否匹配
int isMatchingPair(char opening, char closing) {if (opening == '(' && closing == ')') {return 1;} else if (opening == '[' && closing == ']') {return 1;} else if (opening == '{' && closing == '}') {return 1;} else {return 0;}
}// 判断字符串中的括号是否配对
int isBalanced(char *expression) {Stack stack;initialize(&stack);int len = strlen(expression);for (int i = 0; i < len; i++) {if (expression[i] == '(' || expression[i] == '[' || expression[i] == '{') {push(&stack, expression[i]);} else if (expression[i] == ')' || expression[i] == ']' || expression[i] == '}') {if (isEmpty(&stack)) {return 0;} else if (!isMatchingPair(pop(&stack), expression[i])) {return 0;}}}return isEmpty(&stack);
}int main() {int n;scanf("%d", &n);char expression[MAX_SIZE];fgets(expression, MAX_SIZE, stdin);for (int i = 0; i < n; i++) {fgets(expression, MAX_SIZE, stdin);// 删除末尾的换行符expression[strcspn(expression, "\n")] = '\0';if (isBalanced(expression)) {printf("YES\n");} else {printf("NO\n");}}return 0;
}

该程序首先定义了一个栈的结构体,并实现了栈的相关操作函数。

然后,程序定义了isMatchingPair函数,用于判断两个括号是否匹配。

接下来,程序定义了isBalanced函数,用于判断字符串中的括号是否配对。在函数中,首先创建一个栈,并对其进行初始化。然后,遍历字符串中的每个字符:

  • 如果当前字符是左括号(‘(’、‘[‘或’{’),则将其入栈。

  • 如果当前字符是右括号(‘)’、‘]‘或’}’),则判断栈是否为空。如果栈为空,说明右括号没有对应的左括号,返回0。如果栈不为空,则弹出栈顶的元素,并判断弹出的左括号和当前右括号是否匹配。如果不匹配,返回0。

  • 最后,返回栈是否为空。如果栈为空,说明所有括号都正确配对,返回1;否则,返回0。

main函数中,程序首先读取输入的整数n,表示待判断的字符串数量。然后,使用一个循环依次处理每个字符串。对于每个字符串,调用isBalanced函数判断括号是否配对,并根据结果输出"YES"或"NO"。

第3题:扑克牌排序

假设这里有36张扑克牌,分别为A1A9,B1B9,C1C9,D1D9,其中A代表方片,B代表草花,C代表红桃,D代表黑桃,那么,设定如下的排序规则:
1.对于两张卡牌,X1Y1与X2Y2,X1与X2表示A~D,Y1与Y2表示1~9,如果X1与X2不同,那么依照D>C>B>A的方式进行排序
2.假如有X1与X2相同时,那么就比较Y1与Y2的大小。
例如,对于如下的四张牌,有如下的升序排序结果:
D3,C4,A4,C1
升序排序的结果为A4,C1,C4,D3
有人提出了如下的排序策略:
先建立9个队列,用于存放点数的大小,将卡牌依点数存放入各自的队列之中,然后再按队列1到队列9依次出队。
例如,对于上面的结果,依次进队后,结果如下:
队列1:C1;队列3:D3,队列4:C4,A4
将其依次出队后,结果为C1,D3,C4,A4
然后,再建立4个队列,用于存放花色。将卡牌依花色A~D存放入队列1~4中,然后再按队列1到队列4依次出队。
例如,对于上面刚刚出队的序列C1,D3,C4,A4,将其依次进队,结果如下:
队列1:A4;队列3:C1,C4;队列4:D3
将其依次出队后,结果为A4,C1,C4,D3,排序结束。
请根据上面的算法,编写一个用队列对扑克牌排序的程序,要求依照上面的排序规则,根据先花色后点数的方法进行排序。
时间限制:1000
内存限制:65536
输入
输入分为两行,第一行为一个整数n,表示一共有n张牌(1<=n<=100) 第二行用XY的形式表示每一张牌,其中X为A~D,Y为1~9
输出
输出三个部分 第一个部分为第一次进队出队的结果,用Queue1:…表示,共9行,结果用空格分隔,下同 第二部分为第二次进队出队的结果,用QueueA:…表示,共4行 第三部分为一行,即将卡牌排序后的结果(升序排序)
样例输入
8
D8 A6 C3 B8 C5 A1 B5 D3
样例输出
Queue1:A1
Queue2:
Queue3:C3 D3
Queue4:
Queue5:C5 B5
Queue6:A6
Queue7:
Queue8:D8 B8
Queue9:
QueueA:A1 A6
QueueB:B5 B8
QueueC:C3 C5
QueueD:D3 D8
A1 A6 B5 B8 C3 C5 D3 D8
提示
第二次入队出队时,可以复用第一次时9个队列中的4个。所以其实只需要开辟9个队列即可。

下面是一个使用队列进行扑克牌排序的C语言程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 定义队列结构
typedef struct {char cards[100][3];  // 存放扑克牌的数组int front;  // 队列头指针int rear;  // 队列尾指针
} Queue;// 初始化队列
void initQueue(Queue *queue) {queue->front = 0;queue->rear = 0;
}// 判断队列是否为空
int isEmpty(Queue *queue) {return queue->front == queue->rear;
}// 入队
void enqueue(Queue *queue, char *card) {strcpy(queue->cards[queue->rear], card);queue->rear++;
}// 出队
void dequeue(Queue *queue, char *card) {strcpy(card, queue->cards[queue->front]);queue->front++;
}// 扑克牌排序函数
void sortPoker(int n, char cards[][3]) {Queue queues[9];  // 9个队列int i, j;// 初始化队列for (i = 0; i < 9; i++) {initQueue(&queues[i]);}// 第一次入队出队,按照点数存放到相应的队列中for (i = 0; i < n; i++) {int index = cards[i][1] - '0';  // 获取点数enqueue(&queues[index-1], cards[i]);}// 输出第一次入队出队的结果for (i = 0; i < 9; i++) {printf("Queue%d:", i+1);while (!isEmpty(&queues[i])) {char card[3];dequeue(&queues[i], card);printf(" %s", card);}printf("\n");}// 第二次入队出队,按照花色存放到相应的队列中for (i = 0, j = 0; i < 9; i++) {if (i == 0 || i == 5) {while (!isEmpty(&queues[i])) {char card[3];dequeue(&queues[i], card);enqueue(&queues[j], card);}j++;}}// 输出第二次入队出队的结果for (i = 0; i < 4; i++) {printf("Queue%c:", 'A' + i);while (!isEmpty(&queues[i])) {char card[3];dequeue(&queues[i], card);printf(" %s", card);}printf("\n");}// 对队列进行升序排序for (i = 0; i < 4; i++) {for (j = i + 1; j < 4; j++) {if (strcmp(queues[i].cards[queues[i].front], queues[j].cards[queues[j].front]) > 0) {Queue temp = queues[i];queues[i] = queues[j];queues[j] = temp;}}}// 输出排序后的结果for (i = 0; i < 4; i++) {while (!isEmpty(&queues[i])) {char card[3];dequeue(&queues[i], card);printf("%s ", card);}}printf("\n");
}int main() {int n;scanf("%d", &n);char cards[100][3];for (int i = 0; i < n; i++) {scanf("%s", cards[i]);}sortPoker(n, cards);return 0;
}

使用队列进行排序的思路是先根据点数将扑克牌存放到相应的队列中,然后按照队列的顺序进行出队操作,得到第一次进队出队的结果。接着,根据花色将扑克牌再次存放到相应的队列中,再次按照队列的顺序进行出队操作,得到第二次进队出队的结果。最后对4个队列进行升序排序,并输出排序结果。

注意,程序中的队列实现使用了数组,队列的最大长度为100。程序根据输入的扑克牌数量n进行相应的处理,可以处理1到100张扑克牌的排序。

第4题:滑动窗口

给定一个长度为n(n<=10^6)的数组。有一个大小为k的滑动窗口从数组的最左端移动到最右端。你可以看到窗口中的k个数字。窗口每次向右滑动一个数字的距离。
下面是一个例子:
数组是 [1 3 -1 -3 5 3 6 7], k = 3。
在这里插入图片描述
你的任务是得到滑动窗口在每个位置时的最大值和最小值。
时间限制:20000
内存限制:65536
输入
输入包括两行。 第一行包括n和k,分别表示数组的长度和窗口的大小。 第二行包括n个数字。
输出
输出包括两行。 第一行包括窗口从左至右移动的每个位置的最小值。 第二行包括窗口从左至右移动的每个位置的最大值。
样例输入
8 3
1 3 -1 -3 5 3 6 7
样例输出
-1 -3 -3 -3 3 3
3 3 5 5 6 7

这个问题可以使用滑动窗口来解决。我们可以使用双端队列(deque)来辅助实现。

首先,我们需要定义一个双端队列,用于存储当前窗口中的元素。队列中的元素按照从大到小的顺序排列,且队头元素为当前窗口中的最大值。

然后,我们遍历数组,依次将元素添加到双端队列中。在添加元素之前,我们需要进行一些操作:

  1. 如果队列不为空且队头元素的下标不在当前窗口的范围内,说明队头元素已经不在当前窗口中,可以将其从队列中删除。

  2. 如果队列不为空且队尾元素小于等于当前要添加的元素,说明队尾元素不可能成为后续窗口的最大值,可以将其从队列中删除,以保持队列中元素的有序性。

  3. 将当前元素添加到队列的队尾。

在每次添加元素之后,我们可以得到当前窗口的最大值,即队列的队头元素。同时,我们还需要记录当前窗口的最小值。

下面是使用C语言编写的示例代码:

#include <stdio.h>
#include <stdlib.h>// 双端队列结构体
typedef struct {int* data;  // 数据数组int front;  // 队头指针int rear;   // 队尾指针
} Deque;// 初始化双端队列
void initDeque(Deque* deque, int size) {deque->data = (int*)malloc(sizeof(int) * size);deque->front = 0;deque->rear = -1;
}// 判断队列是否为空
int isEmpty(Deque* deque) {return deque->rear < deque->front;
}// 在队尾插入元素
void insertRear(Deque* deque, int value) {deque->data[++deque->rear] = value;
}// 删除队头元素
void deleteFront(Deque* deque) {deque->front++;
}// 获取队头元素的值
int getFront(Deque* deque) {return deque->data[deque->front];
}int main() {int n, k;scanf("%d %d", &n, &k);// 读取数组元素int* array = (int*)malloc(sizeof(int) * n);for (int i = 0; i < n; i++) {scanf("%d", &array[i]);}Deque minDeque, maxDeque;initDeque(&minDeque, n);initDeque(&maxDeque, n);// 处理前k个元素for (int i = 0; i < k; i++) {// 删除队列中所有小于当前元素的值while (!isEmpty(&minDeque) && array[i] <= array[getFront(&minDeque)]) {deleteFront(&minDeque);}while (!isEmpty(&maxDeque) && array[i] >= array[getFront(&maxDeque)]) {deleteFront(&maxDeque);}// 将当前元素添加到队列中insertRear(&minDeque, i);insertRear(&maxDeque, i);}// 处理剩余元素for (int i = k; i < n; i++) {// 输出当前窗口的最小值和最大值printf("%d ", array[getFront(&minDeque)]);printf("%d ", array[getFront(&maxDeque)]);// 删除队列中所有不在当前窗口中的元素while (!isEmpty(&minDeque) && getFront(&minDeque) <= i - k) {deleteFront(&minDeque);}while (!isEmpty(&maxDeque) && getFront(&maxDeque) <= i - k) {deleteFront(&maxDeque);}// 删除队列中所有小于当前元素的值while (!isEmpty(&minDeque) && array[i] <= array[getFront(&minDeque)]) {deleteFront(&minDeque);}while (!isEmpty(&maxDeque) && array[i] >= array[getFront(&maxDeque)]){deleteFront(&maxDeque);}// 将当前元素添加到队列中insertRear(&minDeque, i);insertRear(&maxDeque, i);}// 输出最后一个窗口的最小值和最大值printf("%d ", array[getFront(&minDeque)]);printf("%d\n", array[getFront(&maxDeque)]);// 释放内存free(array);free(minDeque.data);free(maxDeque.data);return 0;
}

此代码使用双端队列来维护当前窗口的最小值和最大值。它使用了两个双端队列,一个用于存储当前窗口的最小值,另一个用于存储当前窗口的最大值。代码中的initDeque函数用于初始化双端队列,isEmpty函数用于判断队列是否为空,insertRear函数用于在队尾插入元素,deleteFront函数用于删除队头元素,getFront函数用于获取队头元素的值。

代码通过遍历数组来处理窗口中的元素。在每次添加元素之前,它首先删除队列中不在当前窗口范围内的元素,然后删除队列中所有小于当前元素的值,并将当前元素添加到队列的队尾。在处理第一个窗口时,只需遍历前k个元素。在处理剩余的窗口时,我们需要输出当前窗口的最小值和最大值,并删除队列中不在当前窗口中的元素。

最后,我们输出最后一个窗口的最小值和最大值,并释放动态分配的内存。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

力扣:83. 删除排序链表中的重复元素(Python3)

题目&#xff1a; 给定一个已排序的链表的头 head &#xff0c; 删除所有重复的元素&#xff0c;使每个元素只出现一次 。返回 已排序的链表 。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚…

Matlab图像处理-幂次变换

幂次变换 如下图所示的幂次变换函数曲线图&#xff1a; 当γ <1时&#xff0c;效果和对数变换相似&#xff0c;放大暗处细节&#xff0c;压缩亮处细节&#xff0c;随着数值减少&#xff0c;效果越强。 当γ >1时&#xff0c;放大亮处细节&#xff0c;压缩暗处细节&…

Spring Boot框架以及它的优势

文章目录 介绍1. **简化配置**2. **快速启动**3. **自动配置**4. **集成第三方库和框架**5. **微服务支持**6. **内嵌式数据库支持**7. **健康监控和管理**8. **可插拔的开发工具**9. **丰富的社区和生态系统**10. **良好的测试支持&#xff1a;** 核心特性**1. 依赖注入&#…

服务器监控可视化

IT监控可视化是一种将IT监控数据以图形化的方式呈现给用户的技术&#xff0c;可以帮助用户更直观、更易懂地了解IT系统的运行状况。服务器监控可视化是其中的一个重要应用场景&#xff0c;可以将服务器的各种性能指标以图表、仪表盘等形式展示&#xff0c;以便管理员更好地了解…

25.CSS自定义形状按钮与悬停效果

效果 源码 <!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><title>CSS Custom Shape Button</title><link rel="stylesheet" href="style.css"> </head> <body&…

Windows Network File System Remote Code Execution Vulnerability

文章目录 NFS(Network File System)漏洞描述攻击者如何利用此漏洞&#xff1f;该漏洞的危险程度机密性-high真实性-high可用性-high 如何降低漏洞风险推荐阅读 NFS(Network File System)漏洞描述 Name Microsoft Windows Network File System Remote Code Execution Vulnerabi…

Java后端开发面试题——多线程

创建线程的方式有哪些&#xff1f; 继承Thread类 public class MyThread extends Thread {Overridepublic void run() {System.out.println("MyThread...run...");}public static void main(String[] args) {// 创建MyThread对象MyThread t1 new MyThread() ;MyTh…

Vue安装过程的困惑解答——nodejs和vue关系、webpack、vue-cli、vue的项目结构

文章目录 1、为什么在使用vue前要下载nodejs&#xff1f;2、为什么安装nodejs后就能使用NPM包管理工具&#xff1f;3、为什么是V8引擎并且使用C实现&#xff1f;4、为什么会安装淘宝镜像&#xff1f;5、什么是webpack模板&#xff1f;6、什么是脚手架 vue-cli&#xff1f;6.1 安…

【Unity】URP屏幕后处理UI模糊效果实现

这里Canvas(1)设置为Overlay能渲染出指定UI高清&#xff0c;其他UI模糊&#xff0c;然而这做法非常不好&#xff0c;如果此时再打开UI 以及 关闭模糊效果 要将这些置顶UI 恢复到原本Canvas里&#xff0c;也就是要管理2套Canvas using System; using System.Collections; using…

javaee spring 静态代理

静态代理 package com.test.staticProxy;public interface IUsersService {public void insert(); }package com.test.staticProxy;//目标类 public class UsersService implements IUsersService {Overridepublic void insert() {System.out.println("添加用户");…

设计模式—观察者模式(Observer)

目录 思维导图 一、什么是观察者模式&#xff1f; 二、有什么优点吗&#xff1f; 三、有什么缺点吗&#xff1f; 四、什么时候使用观察者模式&#xff1f; 五、代码展示 ①、双向耦合的代码 ②、解耦实践一 ③、解耦实践二 ④、观察者模式 六、这个模式涉及到了哪些…

信息技术02--初/高中--分类选择题(377道题与解析)

文章目录 第一章 办公软件 1-96第二章 信息技术基础 1-41第三章 计算机系统基础 1-28第四章 多媒体技术 1-115第五章 计算机网络技术 1-50第六章 信息安全 1-3第七章 算法与程序简介 1-13第八章 数据结构 1-2第九章 数据库技术 1-20第十章 练习 1-9 第一章 办公软件 1-96 1、某…