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

news2024/11/25 20:35:06

在这里插入图片描述

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

第1题:二叉树的深度

给定一棵二叉树,求该二叉树的深度
二叉树深度定义:从根结点到叶结点依次经过的结点(含根、叶结点)形成树的一条路径,最长路径的节点个数为树的深度
时间限制:1000
内存限制:65535
输入
第一行是一个整数n,表示二叉树的结点个数。二叉树结点编号从1到n,根结点为1,n <= 10 接下来有n行,依次对应二叉树的n个节点。 每行有两个整数,分别表示该节点的左儿子和右儿子的节点编号。如果第一个(第二个)数为-1则表示没有左(右)儿子
输出
输出一个整型数,表示树的深度
样例输入
3
2 3
-1 -1
-1 -1
样例输出
2

以下是使用C语言编写的解决方案:

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

typedef struct Node {
    int value;
    struct Node* left;
    struct Node* right;
} Node;

int maxDepth(Node* root) {
    if (root == NULL) {
        return 0;
    }

    int leftDepth = maxDepth(root->left);
    int rightDepth = maxDepth(root->right);

    return (leftDepth > rightDepth) ? (leftDepth + 1) : (rightDepth + 1);
}

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

Node* buildTree(int n) {
    Node** nodes = (Node**)malloc((n + 1) * sizeof(Node*));
    for (int i = 1; i <= n; i++) {
        nodes[i] = createNode(i);
    }

    for (int i = 1; i <= n; i++) {
        int left, right;
        scanf("%d %d", &left, &right);
        if (left != -1) {
            nodes[i]->left = nodes[left];
        }
        if (right != -1) {
            nodes[i]->right = nodes[right];
        }
    }

    Node* root = nodes[1];
    free(nodes);
    return root;
}

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

    Node* root = buildTree(n);
    int depth = maxDepth(root);

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

    free(root);

    return 0;
}

这段代码实现了二叉树的构建和计算深度。

首先,通过createNode函数创建一个具有给定值的新节点。

然后,buildTree函数根据输入的信息构建二叉树。它首先创建一个节点数组,其中索引从1到n对应于二叉树的节点编号。然后,它遍历n行输入,将每个节点的左儿子和右儿子与相应的节点连接起来。

接下来,maxDepth函数使用递归方式计算二叉树的深度。如果节点为空,说明到达了叶节点的子节点,返回0。否则,递归计算左子树和右子树的深度,并返回较大的深度加1。

最后,将深度输出到屏幕上。

第2题:迷宫

一天Extense在森林里探险的时候不小心走入了一个迷宫,迷宫可以看成是由n * n的格点组成,每个格点只有2种状态,.和#,前者表示可以通行后者表示不能通行。同时当Extense处在某个格点时,他只能移动到东南西北(或者说上下左右)四个方向之一的相邻格点上,Extense想要从点A走到点B,问在不走出迷宫的情况下能不能办到。如果起点或者终点有一个不能通行(为#),则看成无法办到。
时间限制:3000
内存限制:65536
输入
第1行是测试数据的组数k,后面跟着k组输入。每组测试数据的第1行是一个正整数n (1 <= n <= 100),表示迷宫的规模是n * n的。接下来是一个n * n的矩阵,矩阵中的元素为.或者#。再接下来一行是4个整数ha, la, hb, lb,描述A处在第ha行, 第la列,B处在第hb行, 第lb列。注意到ha, la, hb, lb全部是从0开始计数的。
输出
k行,每行输出对应一个输入。能办到则输出“YES”,否则输出“NO”。
样例输入
2
3
.##
…#
#…
0 0 2 2
5

###.#
…#…
###…
…#.
0 0 4 0
样例输出
YES
NO

以下是一个使用C语言编写的解决方案:

#include <stdio.h>

#define MAX_SIZE 100

// 定义迷宫的结构体
typedef struct {
    int n; // 迷宫的规模
    char grid[MAX_SIZE][MAX_SIZE]; // 迷宫的格点
} Maze;

// 初始化迷宫
void initMaze(Maze *maze, int n) {
    maze->n = n;
}

// 读取迷宫的格点
void readGrid(Maze *maze) {
    int i, j;
    for (i = 0; i < maze->n; i++) {
        for (j = 0; j < maze->n; j++) {
            scanf(" %c", &maze->grid[i][j]);
        }
    }
}

// 判断一个格点是否有效
int isValid(int x, int y, Maze *maze) {
    if (x >= 0 && x < maze->n && y >= 0 && y < maze->n && maze->grid[x][y] == '.')
        return 1;
    else
        return 0;
}

// 在迷宫中搜索路径
int searchPath(int x, int y, Maze *maze) {
    if (!isValid(x, y, maze)) // 如果当前格点无效,则返回0
        return 0;

    if (x == maze->n - 1 && y == maze->n - 1) // 如果当前格点是终点,则返回1
        return 1;

    maze->grid[x][y] = '#'; // 将当前格点标记为已访问

    // 递归搜索四个方向的相邻格点
    if (searchPath(x + 1, y, maze) || searchPath(x - 1, y, maze) || searchPath(x, y + 1, maze) || searchPath(x, y - 1, maze))
        return 1;

    return 0;
}

int main() {
    int k, i;
    scanf("%d", &k); // 读取测试数据的组数

    for (i = 0; i < k; i++) {
        int n, ha, la, hb, lb;
        scanf("%d", &n); // 读取迷宫的规模

        Maze maze;
        initMaze(&maze, n); // 初始化迷宫

        readGrid(&maze); // 读取迷宫的格点

        scanf("%d %d %d %d", &ha, &la, &hb, &lb); // 读取起点和终点坐标

        if (maze.grid[ha][la] == '#' || maze.grid[hb][lb] == '#') {
            printf("NO\n"); // 起点或终点无效
        } else {
            if (searchPath(ha, la, &maze))
                printf("YES\n"); // 能到达终点
            else
                printf("NO\n"); // 无法到达终点
        }
    }

    return 0;
}

这个程序首先定义了一个Maze结构体,用于表示迷宫的信息,包括规模和格点的状态。然后通过initMaze函数初始化迷宫,通过readGrid函数读取迷宫的格点。

searchPath函数中,使用递归的方式进行深度优先搜索,搜索四个方向的相邻格点,如果找到终点则返回1,否则返回0。

main函数中,根据输入的测试数据的组数进行循环。每次循环中,读取迷宫的规模、格点、起点和终点的坐标,并调用searchPath函数判断是否能够到达终点,并输出结果。

请注意,该程序假设输入的数据是合法的,即起点和终点都在迷宫的范围内,并且起点和终点的格点都是可通行的。如果输入的数据不符合要求,程序可能会出错。在实际应用中,建议添加错误处理代码来处理异常情况。

第3题:Sequence

给定m个数字序列,每个序列包含n个非负整数。我们从每一个序列中选取一个数字组成一个新的序列,显然一共可以构造出nm个新序列。接下来我们对每一个新的序列中的数字进行求和,一共会得到nm个和,请找出最小的n个和
时间限制:3000
内存限制:65536
输入
输入的第一行是一个整数T,表示测试用例的数量,接下来是T个测试用例的输入 每个测试用例输入的第一行是两个正整数m(0 < m <= 100)和n(0 < n <= 2000),然后有m行,每行有n个数,数字之间用空格分开,表示这m个序列 序列中的数字不会大于10000
输出
对每组测试用例,输出一行用空格隔开的数,表示最小的n个和
样例输入
1
2 3
1 2 3
2 2 3
样例输出
3 3 4

以下是一个使用C语言编写的解决方案:

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

// 比较函数,用于qsort排序
int compare(const void *a, const void *b) {
    return (*(int *)a - *(int *)b);
}

int main() {
    int T;
    scanf("%d", &T); // 读取测试用例的数量

    while (T--) {
        int m, n;
        scanf("%d %d", &m, &n); // 读取m和n

        int i, j;
        int *sequence = (int *)malloc(m * n * sizeof(int)); // 动态分配内存存储序列
        int *sums = (int *)malloc(m * n * sizeof(int)); // 动态分配内存存储和

        for (i = 0; i < m; i++) {
            for (j = 0; j < n; j++) {
                scanf("%d", &sequence[i * n + j]); // 读取序列中的数字
            }
        }

        // 计算和并存储在sums数组中
        for (i = 0; i < m; i++) {
            for (j = 0; j < n; j++) {
                sums[i * n + j] = sequence[i * n + j];
                if (i > 0) {
                    sums[i * n + j] += sums[(i - 1) * n + j];
                }
                if (j > 0) {
                    sums[i * n + j] += sums[i * n + j - 1];
                }
                if (i > 0 && j > 0) {
                    sums[i * n + j] -= sums[(i - 1) * n + j - 1];
                }
            }
        }

        // 使用快速排序对和进行排序
        qsort(sums, m * n, sizeof(int), compare);

        // 输出最小的n个和
        for (i = 0; i < n; i++) {
            printf("%d ", sums[i]);
        }
        printf("\n");

        free(sequence); // 释放内存
        free(sums);
    }

    return 0;
}

该程序首先读取测试用例的数量,并通过循环处理每个测试用例。

在每个测试用例中,首先读取m和n,然后动态分配内存以存储序列和和结果。接下来,使用两层循环读取每个序列的数字,并计算和,将和存储在sums数组中。在计算和时,如果当前位置的行数大于0,则加上上一行的和;如果当前位置的列数大于0,则加上前一列的和;如果当前位置的行数和列数都大于0,则减去左上角的和,以避免重复计算。

之后,使用快速排序(qsort)对和进行排序。最后,输出最小的n个和。

请注意,该程序假设输入的数据是合法的,并且m和n的值在有效范围内。如果输入的数据不符合要求,程序可能会出错。在实际应用中,建议添加错误处理代码来处理异常情况。

第4题:priority queue练习题

我们定义一个正整数a比正整数b优先的含义是:
*a的质因数数目(不包括自身)比b的质因数数目多;
*当两者质因数数目相等时,数值较大者优先级高。
现在给定一个容器,初始元素数目为0,之后每次往里面添加10个元素,每次添加之后,要求输出优先级最高与最低的元素,并把该两元素从容器中删除。
时间限制:2500
内存限制:131072
输入
第一行: num (添加元素次数,num <= 30)
下面10*num行,每行一个正整数n(n < 10000000).
输出
每次输入10个整数后,输出容器中优先级最高与最低的元素,两者用空格间隔。
样例输入
1
10 7 66 4 5 30 91 100 8 9
样例输出
66 5

以下是一个使用C语言编写的解决方案:

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

#define MAX_SIZE 10
#define MAX_PRIME_FACTORS 100

// 结点结构体定义
typedef struct {
    int value; // 数值
    int prime_factors; // 质因数数目
} Node;

// 优先队列结构体定义
typedef struct {
    Node heap[MAX_SIZE]; // 存储结点的数组
    int size; // 当前队列的大小
} PriorityQueue;

// 初始化优先队列
void initQueue(PriorityQueue *queue) {
    queue->size = 0;
}

// 交换两个结点
void swap(Node *a, Node *b) {
    Node temp = *a;
    *a = *b;
    *b = temp;
}

// 上浮操作
void siftUp(PriorityQueue *queue, int index) {
    if (index == 0) // 已经是根节点,不需要上浮
        return;

    int parent = (index - 1) / 2;

    if (queue->heap[parent].prime_factors < queue->heap[index].prime_factors ||
        (queue->heap[parent].prime_factors == queue->heap[index].prime_factors &&
         queue->heap[parent].value < queue->heap[index].value)) {
        swap(&queue->heap[parent], &queue->heap[index]);
        siftUp(queue, parent);
    }
}

// 下沉操作
void siftDown(PriorityQueue *queue, int index) {
    int leftChild = index * 2 + 1;
    int rightChild = index * 2 + 2;
    int max = index;

    if (leftChild < queue->size &&
        (queue->heap[leftChild].prime_factors > queue->heap[max].prime_factors ||
         (queue->heap[leftChild].prime_factors == queue->heap[max].prime_factors &&
          queue->heap[leftChild].value > queue->heap[max].value))) {
        max = leftChild;
    }

    if (rightChild < queue->size &&
        (queue->heap[rightChild].prime_factors > queue->heap[max].prime_factors ||
         (queue->heap[rightChild].prime_factors == queue->heap[max].prime_factors &&
          queue->heap[rightChild].value > queue->heap[max].value))) {
        max = rightChild;
    }

    if (max != index) {
        swap(&queue->heap[max], &queue->heap[index]);
        siftDown(queue, max);
    }
}

// 入队操作
void enqueue(PriorityQueue *queue, int value) {
    if (queue->size == MAX_SIZE) // 队列已满
        return;

    Node node;
    node.value = value;
    node.prime_factors = 0;

    // 统计质因数数目
    int i;
    int temp = value;
    for (i = 2; i * i <= temp; i++) {
        if (temp % i == 0) {
            node.prime_factors++;
            while (temp % i == 0)
                temp /= i;
        }
    }
    if (temp > 1)
        node.prime_factors++;

    queue->heap[queue->size] = node;
    siftUp(queue, queue->size);
    queue->size++;
}

// 出队操作
int dequeue(PriorityQueue *queue) {
    if (queue->size == 0) // 队列为空
        return -1;

    int value = queue->heap[0].value;
    queue->size--;
    queue->heap[0] = queue->heap[queue->size];
    siftDown(queue, 0);

    return value;
}

int main() {
    int num;
    scanf("%d", &num); // 读取添加元素次数

    PriorityQueue queue;
    initQueue(&queue); // 初始化优先队列

    int i, j;
    for (i = 0; i < num; i++) {
        for (j = 0; j < MAX_SIZE; j++) {
            int value;
            scanf("%d", &value); // 读取元素值
            enqueue(&queue, value); // 入队
        }

        int max = dequeue(&queue); // 出队优先级最高的元素
        int min = dequeue(&queue); // 出队优先级最低的元素

        printf("%d %d\n", max, min);
    }

    return 0;
}

该程序使用优先队列(最大堆)来实现。首先定义了结点结构体Node,用来存储元素的数值和质因数数目。然后定义了优先队列结构体PriorityQueue,包含一个存储结点的数组和当前队列的大小。

程序中实现了以下几个函数:

  • initQueue:初始化优先队列。

  • swap:交换两个结点。

  • siftUp:上浮操作,用于调整结点位置以维持最大堆的性质。

  • siftDown:下沉操作,用于调整结点位置以维持最大堆的性质。

  • enqueue:入队操作,将元素插入到优先队列中。

  • dequeue:出队操作,将优先级最高的元素从队列中删除并返回其值。

在主函数中,首先读取添加元素次数num。然后通过循环,依次读取每次添加的10个整数,并调用enqueue函数将它们加入到优先队列中。接着,循环中使用dequeue函数分别从队列中删除优先级最高和最低的元素,并输出它们的值。

请注意,该程序假设输入的数据是合法的,并且每次添加的元素数量为10。如果输入的数据不符合要求,程序可能会出错。在实际应用中,建议添加错误处理代码来处理异常情况。

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

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

相关文章

读SQL学习指南(第3版)笔记10_元数据与大数据

1. 元数据 1.1. metadata 1.2. 关于数据的数据 1.3. 数据字典 1.3.1. ⒅与外键关联的数据表/列 1.3.2. ⒄外键列 1.3.3. ⒃外键名 1.3.4. ⒂存储索引的信息 1.3.5. ⒁索引列的排序&#xff08;升序或降序&#xff09; 1.3.6. ⒀已索引的列 1.3.7. ⑿索引类型&#xf…

CSDN的好处

社区交流&#xff1a;CSDN是一个广大的程序员社区&#xff0c;有很多技术大牛和优秀开发者&#xff0c;可以在这里进行技术交流和讨论&#xff0c;获取最新的技术动态和资源。 学习资源&#xff1a;CSDN上有很多高质量的技术文章、教程和视频资源&#xff0c;可以帮助程序员不…

2023-9-3 筛质数

题目链接&#xff1a;筛质数 埃氏筛法 #include <iostream>using namespace std;const int N 1000010;int cnt; bool st[N];bool get_primes(int n) {for(int i 2; i < n; i ){if(!st[i]){cnt ;for(int j i i; j < n; j i) st[j] true;}} }int main() {int …

linux深入理解多进程间通信

1.进程间通信 1.1 进程间通信目的 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程资源共享&#xff1a;多个进程之间共享同样的资源。通知事件&#xff1a;一个进程需要向另一个或一组进程发送消息&#xff0c;通知它&#xff08;它们&#xff09;发生了某种事件…

AUTOSAR规范与ECU软件开发(实践篇)7.11 MCAL配置验证与代码生成

在配置完所需MCAL模块之后&#xff0c; 就可以进行配置验证与代码生成。MCAL配置工具的工具栏如图7.64所示。 其中&#xff0c; 右起第二个按钮为“Verify selected project”&#xff0c; 点击之后将进行配置验证。 右起第一个按钮为“Generate Code for the currently select…

小小一个设置程序高级感拉满

手动设置 结果如下 代码设置&#xff1a; procedure TForm1.Button1Click(Sender: TObject); begin TStyleManager.TrySetStyle(cbxVclStyles.Text); end;procedure TForm1.FormCreate(Sender: TObject); var StyleName:string; begin for StyleName in TStyleManager.StyleNa…

查询优化器内核剖析之从一个实例看执行计划

学习查询优化器不是我们的目的&#xff0c;而是通过 它&#xff0c;我们掌握 SQL Server 是如何处理我们的 SQL 的&#xff0c;掌握执行计划&#xff0c;掌握为什么产生 I/O 问题&#xff0c; 为什么 CPU 使用老高&#xff0c;为什么你的索引加了不起作用... 如果&#xff0c;…

数学建模--整数规划匈牙利算法的Python实现

目录 1.算法流程简介 2.算法核心代码 3.算法效果展示 1.算法流程简介 #整数规划模型--匈牙利算法求解 """ 整数规划模型及概念&#xff1a;规划问题的数学模型一般由三个因素构成 决策变量 目标函数 约束条件&#xff1b;线性规划即以线性函数为目标函数&a…

Python开源项目月排行 2023年8月

#2023年8月2023年9月2日1facechain一款可以用于打造个人数字形象的深度学习模型工具。用户只需提供最低三张照片即可获得独属于自己的个人形象数字替身。FaceChain 支持在梯度的界面中使用模型训练和推理能力&#xff0c;也支持资深开发者使用 python 脚本进行训练推理。2Qwen-…

CXL寄存器介绍(3)- CXL MMIO

&#x1f525;点击查看精选 CXL 系列文章&#x1f525; &#x1f525;点击进入【芯片设计验证】社区&#xff0c;查看更多精彩内容&#x1f525; &#x1f4e2; 声明&#xff1a; &#x1f96d; 作者主页&#xff1a;【MangoPapa的CSDN主页】。⚠️ 本文首发于CSDN&#xff0c…

【SpringSecurity】六、基于数据库的认证与授权

文章目录 1、数据库表设计2、测试代码准备3、新建安全用户类4、实现UserDetailsService接口5、授权 1、数据库表设计 接下来基于数据库里的用户信息进行登录认证&#xff0c;以RBAC设计表&#xff0c;分别为&#xff1a; 用户表sys_user &#xff1a;除了基本信息外&#xff…

pytorch(b站小土堆学习笔记P1-P15)

P3. Python学习中的两大法宝函数&#xff08;当然也可以用在PyTorch&#xff09; import torch#查看pytorch有哪些指令 print(dir(torch)) print(dir(torch.cuda)) #查看每条指令怎么用 help(torch.cuda.is_available) P4. PyCharm及Jupyter使用及对比 P5 dataset和dataloade…

肖sir__设计测试用例方法之场景法04_(黑盒测试)

设计测试用例方法之场景法 1、场景法主要是针对测试场景类型的&#xff0c;顾也称场景流程分析法。 2、流程分析是将软件系统的某个流程看成路径&#xff0c;用路径分析的方法来设计测试用例。根据流程的顺序依次进行组合&#xff0c;使得流程的各个分支能走到。 举例说明&…

Pinely Round 2 (Div. 1 + Div. 2) F. Divide, XOR, and Conquer(区间dp)

题目 给定长为n(n<1e4)的数组&#xff0c;第i个数为ai(0<ai<2的60次方) 初始时&#xff0c;区间为[1,n]&#xff0c;也即l1&#xff0c;rn&#xff0c; 你可以在[l,r)中指定一个k&#xff0c;将区间分成左半边[l,k]、右半边[k1,r] 1. 如果左半边异或和与异或和的异…

肖sir__设计测试用例方法之判定表06_(黑盒测试)

设计测试用例方法之判定表 1、判定表&#xff1a;是一种表达逻辑判断的工具。 2、判定表&#xff1a;包含四部分 1&#xff09;条件桩&#xff08;condition stub&#xff09;:列出问题的 所有条件&#xff08;通常条件次序无关紧要&#xff09;。 2&#xff09;条件项&#x…

面试官:介绍一下CSS定位?absolute和relative分别依据什么定位?

能说服一个人的&#xff0c;从来不是道理&#xff0c;而是南墙。 一、position属性介绍 取值名称效果static静态定位(默认值)元素按照标准流布局 (不脱标) , top、bottom、left 、right等属性不起作用relative相对定位元素按照标准流布局 (不脱标) &#xff0c;可以通过top、b…

Medium:做AB test需要多少时间?

文章链接&#xff1a;https://medium.com/alfredcamera/%E5%81%9A-ab-test-%E9%9C%80%E8%A6%81%E5%A4%9A%E5%B0%91%E6%99%82%E9%96%93-c401fbe00eb0 其中&#xff0c;最关键的是确定&#xff1a;总共需要多少样本数量。由以下2个指标决定&#xff1a; 由工具得到&#xff1a; 特…

监听器Listener -,钝化,活化,利用监听器实现简易版 统计网站在线用户功能

监听绑定到HttpSession域中某个对象状态 1.HttpSessionBindingListener 实体类 package com.etime.enetity;import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener;//此处需要实现HttpSessionBindingListener接口&…

使用MDK5的一些偏僻使用方法和谋个功能的作用

程序下载后无法运行 需要勾选如下库&#xff0c;是优化后的库&#xff1b; MicroLib和标准C库之间的主要区别是: 1、MicroLib是专为深度嵌入式应用程序而设计的。 2、MicroLib经过优化&#xff0c;比使用ARM标准库使用更少的代码和数据内存。 3、MicroLib被设计成在没有操作…

科技成果鉴定之鉴定测试报告

鉴定测试 由于软件类科技成果的复杂、内部结构难以鉴别等特点&#xff0c;我们提供了软件类科技成果鉴定测试服务。软件类科技成果鉴定测试是依据其科研项目计划任务书或技术合同书&#xff0c;参照相应的国家标准对要申请鉴定的软件类科技成果进行的一种符合性测试&#xff0…