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

news2024/11/22 20:52:03

在这里插入图片描述

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

第1题:红与黑

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





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

以下是一个使用深度优先搜索算法(DFS)解决该问题的示例C语言程序:

#include <stdio.h>

#define MAX_SIZE 20

int W, H;
char tiles[MAX_SIZE][MAX_SIZE];
int visited[MAX_SIZE][MAX_SIZE];

int dfs(int x, int y) {
    if (x < 0 || x >= W || y < 0 || y >= H || tiles[y][x] != '.' || visited[y][x])
        return 0;

    visited[y][x] = 1;
    int count = 1;

    count += dfs(x - 1, y); // 左
    count += dfs(x + 1, y); // 右
    count += dfs(x, y - 1); // 上
    count += dfs(x, y + 1); // 下

    return count;
}

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

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

        // 初始化visited数组
        for (int i = 0; i < H; i++) {
            for (int j = 0; j < W; j++) {
                visited[i][j] = 0;
            }
        }

        int result = dfs(start_x, start_y);
        printf("%d\n", result);
    }

    return 0;
}

该程序首先读取输入的W和H,然后读取瓷砖颜色信息,并找到你所站立的黑色瓷砖的位置。接下来,使用深度优先搜索算法从起始位置开始遍历与之相邻的黑色瓷砖,并标记已访问过的瓷砖。最后,统计访问过的瓷砖数量并输出结果。

注意:该程序假设输入是正确的,即输入的瓷砖数量不超过20,且起始位置字符’@'在每个数据集合中唯一出现一次。在实际应用中,你可能需要添加一些错误处理代码来处理无效的输入情况。

第2题:重建二叉树

给定一棵二叉树的前序遍历和中序遍历的结果,求其后序遍历。
时间限制:1000
内存限制:65536
输入
输入可能有多组,以EOF结束。 每组输入包含两个字符串,分别为树的前序遍历和中序遍历。每个字符串中只包含大写字母且互不重复。
输出
对于每组输入,用一行来输出它后序遍历结果。
样例输入
DBACEGF ABCDEFG
BCAD CBAD
样例输出
ACBFGED
CDAB

为了解决该问题,我们可以使用递归的方法来重建二叉树,并输出后序遍历结果。下面是一个使用C语言实现的示例程序:

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

typedef struct TreeNode {
    char val;
    struct TreeNode* left;
    struct TreeNode* right;
} TreeNode;

TreeNode* buildTree(char* preorder, char* inorder, int preStart, int preEnd, int inStart, int inEnd) {
    if (preStart > preEnd || inStart > inEnd)
        return NULL;

    // 创建根节点
    TreeNode* root = (TreeNode*)malloc(sizeof(TreeNode));
    root->val = preorder[preStart];
    root->left = NULL;
    root->right = NULL;

    // 在中序遍历中找到根节点的索引
    int rootIndex;
    for (int i = inStart; i <= inEnd; i++) {
        if (inorder[i] == root->val) {
            rootIndex = i;
            break;
        }
    }

    int leftSubtreeSize = rootIndex - inStart;

    // 递归构建左子树和右子树
    root->left = buildTree(preorder, inorder, preStart + 1, preStart + leftSubtreeSize, inStart, rootIndex - 1);
    root->right = buildTree(preorder, inorder, preStart + leftSubtreeSize + 1, preEnd, rootIndex + 1, inEnd);

    return root;
}

void postorderTraversal(TreeNode* root) {
    if (root == NULL)
        return;

    // 后序遍历:左子树 -> 右子树 -> 根节点
    postorderTraversal(root->left);
    postorderTraversal(root->right);
    printf("%c", root->val);
}

int main() {
    char preorder[100];
    char inorder[100];

    while (scanf("%s %s", preorder, inorder) != EOF) {
        int n = strlen(preorder);
        TreeNode* root = buildTree(preorder, inorder, 0, n - 1, 0, n - 1);
        postorderTraversal(root);
        printf("\n");
    }

    return 0;
}

该程序首先定义了一个树节点的结构体 TreeNode,其中包含节点的值 val,以及左子树和右子树的指针。然后,使用递归的方式实现了 buildTree 函数,该函数根据前序遍历和中序遍历的结果构建二叉树。最后,使用递归的方式实现了 postorderTraversal 函数,用于后序遍历输出结果。

main 函数中,程序通过循环读取输入的前序遍历和中序遍历字符串,并调用 buildTree 构建二叉树,然后调用 postorderTraversal 函数输出后序遍历结果。

请注意,该程序假设输入的前序遍历和中序遍历结果是合法的,且每个字符在遍历结果中都是唯一的。在实际应用中,你可能需要添加一些错误处理代码来处理无效的输入情况。

第3题:快速堆猪

小明有很多猪,他喜欢玩叠猪游戏,就是将猪一头头叠起来。猪叠上去后,还可以把顶上的猪拿下来。小明知道每头猪的重量,而且他还随时想知道叠在那里的猪最轻的是多少斤。
时间限制:1000
内存限制:65536
输入
有三种输入 1)push n n是整数(0<=0 <=20000),表示叠上一头重量是n斤的新猪 2)pop 表示将猪堆顶的猪赶走。如果猪堆没猪,就啥也不干 3)min 表示问现在猪堆里最轻的猪多重。如果猪堆没猪,就啥也不干 输入总数不超过100000条
输出
对每个min输入,输出答案。如果猪堆没猪,就啥也不干
样例输入
pop
min
push 5
push 2
push 3
min
push 4
min
样例输出
2
2

为了解决该问题,我们可以使用堆数据结构来实现猪的叠放和查询最轻猪的操作。下面是一个使用C语言实现的示例程序:

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

typedef struct Pig {
    int weight;
    struct Pig* next;
} Pig;

Pig* top = NULL;

void push(int weight) {
    Pig* newPig = (Pig*)malloc(sizeof(Pig));
    newPig->weight = weight;
    newPig->next = top;
    top = newPig;
}

void pop() {
    if (top == NULL)
        return;

    Pig* temp = top;
    top = top->next;
    free(temp);
}

int min() {
    if (top == NULL)
        return -1;

    int minWeight = top->weight;
    Pig* current = top->next;
    while (current != NULL) {
        if (current->weight < minWeight)
            minWeight = current->weight;
        current = current->next;
    }

    return minWeight;
}

int main() {
    char operation[10];
    int weight;

    while (scanf("%s", operation) != EOF) {
        if (strcmp(operation, "push") == 0) {
            scanf("%d", &weight);
            push(weight);
        } else if (strcmp(operation, "pop") == 0) {
            pop();
        } else if (strcmp(operation, "min") == 0) {
            int minWeight = min();
            if (minWeight != -1)
                printf("%d\n", minWeight);
        }
    }

    return 0;
}

该程序定义了一个猪的结构体 Pig,其中包含猪的重量 weight 和指向堆顶下一头猪的指针 next。然后,使用链表来实现堆数据结构,使用 top 指针来指示堆顶的猪。

程序实现了 push 函数用于将一头新猪叠放在堆顶, pop 函数用于将堆顶的猪赶走, min 函数用于查询猪堆里最轻的猪的重量。

main 函数中,程序通过循环读取输入的操作和猪的重量,并调用相应的函数来执行操作和查询最轻猪的重量。

请注意,该程序假设输入的操作合法且符合要求。在实际应用中,你可能需要添加一些错误处理代码来处理无效的输入情况。

第4题:表达式·表达式树·表达式求值

众所周知,任何一个表达式,都可以用一棵表达式树来表示。例如,表达式a+b*c,可以表示为如下的表达式树:
+
/ \
a *
/ \
b c
现在,给你一个中缀表达式,这个中缀表达式用变量来表示(不含数字),请你将这个中缀表达式用表达式二叉树的形式输出出来。
时间限制:1000
内存限制:65535
输入
输入分为三个部分。 第一部分为一行,即中缀表达式(长度不大于50)。中缀表达式可能含有小写字母代表变量(a-z),也可能含有运算符(+、-、*、/、小括号),不含有数字,也不含有空格。 第二部分为一个整数n(n < 10),表示中缀表达式的变量数。 第三部分有n行,每行格式为C x,C为变量的字符,x为该变量的值。
输出
输出分为三个部分,第一个部分为该表达式的逆波兰式,即该表达式树的后根遍历结果。占一行。 第二部分为表达式树的显示,如样例输出所示。如果该二叉树是一棵满二叉树,则最底部的叶子结点,分别占据横坐标的第1、3、5、7……个位置(最左边的坐标是1),然后它们的父结点的横坐标,在两个子结点的中间。如果不是满二叉树,则没有结点的地方,用空格填充(但请略去所有的行末空格)。每一行父结点与子结点中隔开一行,用斜杠(/)与反斜杠(\)来表示树的关系。/出现的横坐标位置为父结点的横坐标偏左一格,\出现的横坐标位置为父结点的横坐标偏右一格。也就是说,如果树高为m,则输出就有2m-1行。 第三部分为一个整数,表示将值代入变量之后,该中缀表达式的值。需要注意的一点是,除法代表整除运算,即舍弃小数点后的部分。同时,测试数据保证不会出现除以0的现象。
样例输入
a+b*c
3
a 2
b 7
c 5
样例输出
abc*+
+
/ \
a *
/ \
b c
37

为了解决这个问题,我们可以使用递归的方式构建表达式树,并且同时输出逆波兰表达式。下面是一个使用C语言实现的示例程序:

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

typedef struct Node {
    char data;
    struct Node* left;
    struct Node* right;
} Node;

Node* createNode(char data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->left = NULL;
    newNode->right = NULL;
    return newNode;
}

int isOperator(char c) {
    if (c == '+' || c == '-' || c == '*' || c == '/')
        return 1;
    return 0;
}

int isOperand(char c) {
    if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
        return 1;
    return 0;
}

void buildExpressionTree(char* infix, int n, char** variables, int* values, Node** root) {
    int i;
    Node* stack[n];
    int top = -1;

    for (i = 0; i < strlen(infix); i++) {
        if (isOperand(infix[i])) {
            int j;
            char variable = infix[i];
            int value = 0;

            for (j = 0; j < n; j++) {
                if (variables[j][0] == variable) {
                    value = values[j];
                    break;
                }
            }

            Node* operandNode = createNode(variable);
            stack[++top] = operandNode;
        } else if (isOperator(infix[i])) {
            Node* operatorNode = createNode(infix[i]);
            operatorNode->right = stack[top--];
            operatorNode->left = stack[top--];
            stack[++top] = operatorNode;
        }
    }

    *root = stack[top--];
}

void postOrderTraversal(Node* root) {
    if (root != NULL) {
        postOrderTraversal(root->left);
        postOrderTraversal(root->right);
        printf("%c", root->data);
    }
}

int evaluateExpressionTree(Node* root) {
    if (root != NULL) {
        if (isOperand(root->data)) {
            return root->data - 'a' + 1;
        } else {
            int leftValue = evaluateExpressionTree(root->left);
            int rightValue = evaluateExpressionTree(root->right);

            switch (root->data) {
                case '+':
                    return leftValue + rightValue;
                case '-':
                    return leftValue - rightValue;
                case '*':
                    return leftValue * rightValue;
                case '/':
                    return leftValue / rightValue;
            }
        }
    }

    return 0;
}

void printExpressionTree(Node* root, int level) {
    int i;

    if (root == NULL)
        return;

    printExpressionTree(root->right, level + 1);

    for (i = 0; i < level - 1; i++)
        printf(" ");

    if (level > 0)
        printf("/");

    printf("%c\n", root->data);

    printExpressionTree(root->left, level + 1);
}

int main() {
    char infix[51];
    int n;
    int i;

    scanf("%s", infix);
    scanf("%d", &n);

    char* variables[n];
    int values[n];

    for (i = 0; i < n; i++) {
        variables[i] = (char*)malloc(2 * sizeof(char));
        scanf("%s %d", variables[i], &values[i]);
    }

    Node* root = NULL;
    buildExpressionTree(infix, n, variables, values, &root);

    postOrderTraversal(root);
    printf("\n");

    printExpressionTree(root, 0);

    int result = evaluateExpressionTree(root);
    printf("%d\n", result);

    return 0;
}

程序中定义了一个表示表达式树的结构体 Node,其中包含数据 data 和指向左子树和右子树的指针 leftright。函数 createNode 用于创建一个新的节点。

程序中使用栈来构建表达式树。在 buildExpressionTree 函数中,我们遍历中缀表达式的每个字符,如果遇到操作数,则创建一个叶子节点,并将其压入栈中;如果遇到操作符,则创建一个新节点,并将栈顶的两个节点分别设置为新节点的左右子树,然后将新节点压入栈中。最后,栈顶即为整个表达式树的根节点。

postOrderTraversal 函数中,我们使用后根遍历输出逆波兰表达式。

evaluateExpressionTree 函数中,我们使用递归的方式计算表达式树的值。如果节点是操作数,则返回变量对应的值;如果节点是操作符,则递归计算左子树和右子树的值,并根据操作符进行相应的运算。

printExpressionTree 函数中,我们使用递归的方式打印表达式树的显示。通过先打印右子树、根节点、再打印左子树的顺序,可以得到正确的显示结果。

main 函数中,我们读取输入的中缀表达式、变量数量和变量值,并调用 buildExpressionTree 函数构建表达式树。然后,分别调用 postOrderTraversal 函数输出逆波兰表达式、printExpressionTree 函数输出表达式树的显示,并调用 evaluateExpressionTree 函数计算表达式树的值,并输出结果。

请注意,该程序假设输入的中缀表达式合法且符合要求。在实际应用中,你可能需要添加一些错误处理代码来处理无效的输入情况。

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

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

相关文章

闲鱼的商品结构化是如何演进的

闲鱼商品结构化和淘宝/天猫最大的区别在于闲鱼卖家都是个人用户&#xff0c;无论是专业程度还是行动力远不及淘宝卖家。为了不阻碍商品发布&#xff0c;闲鱼一直倡导轻发布&#xff0c;理想状况用户拍完照片输入一段描述即可完成发布。但是这和商品结构化相悖&#xff1a;卖家输…

基于php+thinkphp+vue的校园二手交易网站

运行环境 开发语言&#xff1a;PHP 数据库:MYSQL数据库 应用服务:apache服务器 使用框架:ThinkPHPvue 开发工具:VScode/Dreamweaver/PhpStorm等均可 项目简介 随着社会的发展&#xff0c;社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发…

Folium 笔记:使用PopUp突出subzone的空间分布

0 效果图 点开某一个区域后&#xff0c;内容是这个区域的用地类型分布 1 读取数据 import folium import matplotlib.pyplot as plt import re import geopandas as gpd subzonegpd.read_file(MasterPlan2019PlanningAreaBoundaryNoSea.geojson) subzone 2 提取subzone 信息 …

thinkphp6

unexpected , expecting case (T_CASE) or default (T_DEFAULT) or } 在模板中应用{switch}{/switch}标签,报错,其实是switch的问题&#xff0c;模板解析后&#xff0c;switch:和第一个case:之间不能有有输出的&#xff0c;一个空格也不行&#xff0c;所以第一个要紧跟着 Thi…

【LeetCode刷题(数据结构)】:对称二叉树

给你一个二叉树的根节点 root 检查它是否轴对称 输入&#xff1a;root [1,2,2,3,4,4,3] 输出&#xff1a;true 输入&#xff1a;root [1,2,2,null,3,null,3] 输出&#xff1a;false 提示&#xff1a; 树中节点数目在范围 [1, 1000] 内 -100 < Node.val < 100 对称二叉…

芯片学习记录AM26LS31INSR

AM26LS31INSR 芯片介绍 AM26LS31 系列器件是四路互补输出线路驱动器&#xff0c;可 满足 ANSI TIA/EIA-422-B 和 ITU &#xff08;原 CCITT &#xff09;建议 V.11 的要求。三态输出可提供用于驱动双绞线或平行 双线传输线路等平衡线路的高电流&#xff0c;并在断电情况下处…

C# 解决从其他地方迁移项目,引用中大多数包是感叹号的问题

当在 Visual Studio 中复制别人的 C# 项目时&#xff0c;遇到许多包冒感叹号的问题通常是因为缺少相关的 NuGet 包或引用不正确导致的。这会在解决方案资源管理器中的引用下显示感叹号。 解决办法如下&#xff1a; 在 Visual Studio 中打开项目。 在解决方案资源管理器中&…

Ubuntu 上传项目到 GitHub

一、前言 GitHub 作为时下最大的开源代码管理项目&#xff0c;广泛被工程和科研人员使用&#xff0c;本文主要介绍如何如何将自己的项目程序上传到 GitHub 上。 要上传本地项目到 GitHub 上&#xff0c;主要分为两步&#xff0c;第一步是 二、创建 SSH keys 首先登录 GitHu…

[Linux打怪升级之路]-管道

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 本期学习目标&…

SystemVerilog Assertions应用指南 第一章(1.25章节 “throughout”运算符)

蕴含( (implication)是目前讨论到的允许定义前提条件的一项技术。例如,要对一个指定的序列进行检验,必须某个前提条件为真。也有这样的情况,要求在检验序列的整个过程中,某个条件必须一直为真。蕴含只在时钟边沿检验前提条件一次,然后就开始检验后续算子部分,因此它不检测先行算…

“一馆一策”保亚运,精准气象服务背后的数据魔法

第十九届杭州亚运会已隆重闭幕&#xff0c;十五个比赛日留下了无数精彩的瞬间&#xff1a;开幕式数字火炬手点燃主火炬、男女100米接力赛的激情澎湃、“时间孤勇者”丘索维金娜的坚持、围棋选手柯洁的泪洒赛场…… 作为亚洲水平最高的综合型运动会&#xff0c;本届杭州亚运会竞…

指令跳转:原来if...else就是goto

目录 CPU 是如何执行指令的&#xff1f; 从 if…else 来看程序的执行和跳转 如何通过 if…else 和 goto 来实现循环&#xff1f; 小结 你平时写的程序中&#xff0c;肯定不只有 int a 1 这样最最简单的代码或者指令。我们总是要用到 if…else 这样的条件判断语句、while 和…

教你怎么在电脑端下载西瓜视频源文件

家里长辈平时爱用西瓜视频&#xff0c;看到喜欢的广场舞就会收藏&#xff0c;甚至想下载到视频机&#xff0c;晚上去广场跟着跳&#x1f923;。 这时计算机专业出身的我&#xff0c;就派上用场了。不废话&#xff0c;直接上手&#xff1a; 打开西瓜视频官网&#xff0c;搜索到…

SystemVerilog Assertions应用指南 第一章(1.27章节 “within”运算符)

“ within”构造允许在一个序列中定义另一个序列。 seq1 within seq2 这表示seq1在seq2的开始到结束的范围内发生,且序列seq2的开始匹配点必须在seq1的开始匹配点之前发生,序列seq1的结束匹配点必须在seq2的结束匹配点之前结束。属性p32检查序列s32a在信号“ start”的上升沿和…

【Redis】Java客户端使用list命令

lpush/lrange rpush/rpop/lpop blpop/brpop llen

SQL Server——数据与表的操作

SQL Server 一、实验目的二、实验内容三、实验要求四、实验过程图形化界面完成此实验使用SQL语句进行创建数据库、表格&#xff0c;修改数据库内容、删除数据库 五、实验心得与体会&#xff1a; 一、实验目的 1)熟悉management studio环境。2)掌握management studio环境下创建…

Hadoop3教程(五):NameNode和SecondaryNameNode

文章目录 &#xff08;59&#xff09;NN和2NN的工作机制&#xff08;60&#xff09;FsImage镜像文件&#xff08;61&#xff09;Edits编辑日志&#xff08;62&#xff09;Checkpoint时间设置参考文献 &#xff08;59&#xff09;NN和2NN的工作机制 NameNode的数据是存储在磁盘…

TLP2168

学习记录一下TLP2168 光耦&#xff08;Optocoupler&#xff09;是一种将电气信号转换为光信号再转换回电气信号的装置。它通常由一个发光二极管&#xff08;LED&#xff09;和一个光敏三极管&#xff08;Phototransistor&#xff09;或光敏二极管组成。光耦在电子电路中起到隔…

带你清晰理解二叉树的递归与解题思路(框架思维!)

文章目录 前言&#xff1a;&#x1f415;啥叫“框架思维”&#x1f3e8;深入理解前中后序&#x1fa80;前序位置与后序位置区别 两种解题思路&#xff1a;下面用几道简单题来练习一下&#xff1a;&#x1f380;力扣 104.二叉树的最大深度&#x1f380;力扣 144.翻转二叉树 前言…

树莓派部署.net core控制台程序

1、在自己的电脑上使用VS写一个Net6.0的控制台程序&#xff0c;我假设我就写个Helloworld。 发布项目 使用mobaxterm上传程序 就传三个文件就行 回到在mobaxterm中&#xff0c;进入目录输入&#xff1a;cd consolepublish,运行程序&#xff1a; dotnet ConsoleApp1.dll 输出h…