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

news2024/9/24 20:29:44

在这里插入图片描述

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

第1题:道路

N个以 1 … N 标号的城市通过单向的道路相连:。每条道路包含两个参数:道路的长度和需要为该路付的通行费(以金币的数目来表示)
Bob and Alice 过去住在城市 1.在注意到Alice在他们过去喜欢玩的纸牌游戏中作弊后,Bob和她分手了,并且决定搬到城市N。他希望能够尽可能快的到那,但是他囊中羞涩。我们希望能够帮助Bob找到从1到N最短的路径,前提是他能够付的起通行费。
时间限制:1000
内存限制:65536
输入
第一行包含一个整数K, 0 <= K <= 10000, 代表Bob能够在他路上花费的最大的金币数。第二行包含整数N, 2 <= N <= 100, 指城市的数目。第三行包含整数R, 1 <= R <= 10000, 指路的数目. 接下来的R行,每行具体指定几个整数S, D, L 和 T来说明关于道路的一些情况,这些整数之间通过空格间隔: S is 道路起始城市, 1 <= S <= N D is 道路终点城市, 1 <= D <= N L is 道路长度, 1 <= L <= 100 T is 通行费 (以金币数量形式度量), 0 <= T <=100 注意不同的道路可能有相同的起点和终点。
输出
输入结果应该只包括一行,即从城市1到城市N所需要的最小的路径长度(花费不能超过K个金币)。如果这样的路径不存在,结果应该输出-1。
样例输入
5
6
7
1 2 2 3
2 4 3 3
3 4 2 4
1 3 4 1
4 6 2 1
3 5 2 0
5 4 3 2
样例输出
11

这个问题可以使用Dijkstra算法来解决,用于找到从城市1到城市N的最短路径。

以下是一个解决道路问题的C语言程序:

#include <stdio.h>
#include <stdbool.h>
#include <limits.h>

#define MAX_N 100
#define MAX_R 100

// 定义道路结构
typedef struct {
    int dest;
    int length;
    int toll;
} Road;

int dijkstra(int K, int N, int R, Road roads[][MAX_R]) {
    int distance[MAX_N];
    bool visited[MAX_N];
    int i, j;

    // 初始化距离数组和访问标记数组
    for (i = 1; i <= N; i++) {
        distance[i] = INT_MAX;
        visited[i] = false;
    }

    // 设置起点城市1的距离为0
    distance[1] = 0;

    // 执行N-1次迭代
    for (i = 1; i < N; i++) {
        int minDistance = INT_MAX;
        int minIndex = -1;

        // 找到距离最小且未被访问的城市
        for (j = 1; j <= N; j++) {
            if (!visited[j] && distance[j] < minDistance) {
                minDistance = distance[j];
                minIndex = j;
            }
        }

        if (minIndex == -1) {
            break;  // 所有城市都已访问,退出循环
        }

        visited[minIndex] = true;

        // 更新与当前城市相邻的城市的距离
        for (j = 0; j < R; j++) {
            Road road = roads[minIndex][j];
            if (road.dest != -1 && distance[minIndex] + road.length <= K && distance[minIndex] + road.length + road.toll < distance[road.dest]) {
                distance[road.dest] = distance[minIndex] + road.length + road.toll;
            }
        }
    }

    return distance[N];
}

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

    Road roads[MAX_N][MAX_R];
    int i, j;
    for (i = 1; i <= N; i++) {
        for (j = 0; j < R; j++) {
            roads[i][j].dest = -1;  // 初始化道路目的地为-1表示无效
        }
    }

    for (i = 0; i < R; i++) {
        int S, D, L, T;
        scanf("%d %d %d %d", &S, &D, &L, &T);
        for (j = 0; j < R; j++) {
            if (roads[S][j].dest == -1) {
                roads[S][j].dest = D;
                roads[S][j].length = L;
                roads[S][j].toll = T;
                break;
            }
        }
    }

    int result = dijkstra(K, N, R, roads);
    if (result == INT_MAX) {
        printf("-1\n");
    } else {
        printf("%d\n", result);
    }

    return 0;
}

在这个解决方案中,我们首先读取输入的金币数K、城市数N和道路数R。

然后,我们创建一个大小为MAX_N×MAX_R的二维数组roads,用于存储道路的信息。

接下来,我们初始化roads数组的每个元素的目的地为-1,表示无效。然后,我们根据输入的道路信息,将相应的目的地、长度和通行费存储在roads数组中。

然后,我们调用dijkstra函数进行Dijkstra算法的执行。该函数接受金币数K、城市数N、道路数R和roads数组作为参数,返回从城市1到城市N的最短路径长度。

dijkstra函数中,我们首先初始化距离数组distance和访问标记数组visited。然后,我们设置起点城市1的距离为0。

接下来,我们进行N-1次迭代。在每次迭代中,我们找到距离最小且未被访问的城市,将其标记为已访问,并更新与该城市相邻的城市的距离。我们只更新满足以下条件的城市:未被访问、从当前城市到相邻城市的距离不超过K,并且经过该道路的通行费加上当前城市的距离小于相邻城市的当前距离。

最后,我们返回距离数组中城市N的距离作为最终结果。如果距离数组中城市N的值为INT_MAX,表示不存在满足条件的路径,输出-1;否则,输出该值。

综上所述,这个C语言程序可以根据输入的金币数、城市数和道路信息,计算出从城市1到城市N的最短路径长度,并输出结果。

第2题:Rainbow的商店

Rainbow开了一家商店,在一次进货中获得了N个商品。
已知每个商品的利润和过期时间。
Rainbow每天只能卖一个商品,并且过期商品不能再卖。
Rainbow也可以选择在每天出售哪个商品,并且一定可以卖出。
由于这些限制,Rainbow需要制定一份合理的售卖计划。请你计算一下,Rainbow最终可以获得的最大收益。
时间限制:1000
内存限制:262144
输入
第一行两个整数N。 接下来N行每行两个整数,分别表示每个商品的利润、过期时间。 1<=N,利润,时间<=10000。
输出
输出一个整数,表示Rainbow最终可以获得的最大收益。
样例输入
7
20 1
2 1
10 3
100 2
8 2
5 20
50 10
样例输出
185
提示
第1天卖出20 第2天卖出100 第3天卖出10 第4天卖出50(实际上只要在第10天卖就可以) 第5天卖出5(实际上只要在第20天前卖就可以) 总计185 其它2件商品由于过期、每天只能卖一个的限制,在最优策略下应该不出售。

这个问题可以使用动态规划来解决。我们可以定义一个状态数组dp,其中dp[i]表示在第i天能够获得的最大收益。

以下是一个解决Rainbow商店问题的C语言程序:

#include <stdio.h>

#define MAX_N 100

int maxProfit(int N, int profits[], int expiration[]) {
    int dp[MAX_N + 1] = {0};
    int i, j;

    for (i = 1; i <= N; i++) {
        int maxProfit = profits[i];  // 假设卖出当前商品
        for (j = 1; j < i; j++) {
            if (i - j <= expiration[j] && dp[j] + profits[i] > maxProfit) {
                maxProfit = dp[j] + profits[i];  // 更新最大收益
            }
        }
        dp[i] = maxProfit;
    }

    return dp[N];
}

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

    int profits[MAX_N];
    int expiration[MAX_N];
    int i;
    for (i = 1; i <= N; i++) {
        scanf("%d %d", &profits[i], &expiration[i]);
    }

    int result = maxProfit(N, profits, expiration);
    printf("%d\n", result);

    return 0;
}

在这个解决方案中,我们首先读取输入的商品数量N。

然后,我们创建两个数组profitsexpiration,分别用于存储商品的利润和过期时间。

接下来,我们使用循环读取每个商品的利润和过期时间,并将它们存储在相应的数组中。

然后,我们调用maxProfit函数计算Rainbow最终可以获得的最大收益。该函数接受商品数量N、利润数组profits和过期时间数组expiration作为参数,返回最大收益。

maxProfit函数中,我们定义一个状态数组dp,并初始化为0。然后,我们进行迭代计算每一天的最大收益。

对于第i天,我们假设卖出当前商品,将其利润加到当前最大收益中。然后,我们遍历第i天之前的每一天j,如果卖出第j天的商品可以在第i天之前卖出,并且卖出第j天的商品加上当前商品的利润可以得到更大的收益,就更新最大收益。

最后,我们返回dp[N]作为最终结果,即Rainbow最终可以获得的最大收益。

综上所述,这个C语言程序可以根据输入的商品利润和过期时间,计算出Rainbow最终可以获得的最大收益,并输出结果。

第3题:冰阔落

老王喜欢喝冰阔落。
初始时刻,桌面上有n杯阔落,编号为1到n。老王总想把其中一杯阔落倒到另一杯中,这样他一次性就能喝很多很多阔落,假设杯子的容量是足够大的。
有m 次操作,每次操作包含两个整数x与y。
若原始编号为x 的阔落与原始编号为y的阔落已经在同一杯,请输出"Yes";否则,我们将原始编号为y 所在杯子的所有阔落,倒往原始编号为x 所在的杯子,并输出"No"。
最后,老王想知道哪些杯子有冰阔落。
时间限制:10000
内存限制:65536
输入
有多组测试数据,少于 5 组。 每组测试数据,第一行两个整数 n, m (n, m<=50000)。接下来 m 行,每行两个整数 x, y (1<=x, y<=n)。
输出
每组测试数据,前 m 行输出 “Yes” 或者 “No”。 第 m+1 行输出一个整数,表示有阔落的杯子数量。 第 m+2 行有若干个整数,从小到大输出这些杯子的编号。
样例输入
3 2
1 2
2 1
4 2
1 2
4 3
样例输出
No
Yes
2
1 3
No
No
2
1 4

这个问题可以使用并查集(Disjoint Set)来解决。我们可以创建一个数组parent,用于记录每个杯子所属的集合。

以下是一个解决"冰阔落 I"问题的C语言程序:

#include <stdio.h>

#define MAX_N 50000

int parent[MAX_N + 1];  // 并查集数组

int find(int x) {
    if (parent[x] == x) {
        return x;
    }
    return parent[x] = find(parent[x]);  // 路径压缩
}

void merge(int x, int y) {
    int px = find(x);
    int py = find(y);
    if (px != py) {
        parent[py] = px;
    }
}

int main() {
    int n, m;
    while (scanf("%d %d", &n, &m) == 2) {
        int i;
        for (i = 1; i <= n; i++) {
            parent[i] = i;  // 初始化并查集
        }

        for (i = 1; i <= m; i++) {
            int x, y;
            scanf("%d %d", &x, &y);
            if (find(x) == find(y)) {
                printf("Yes\n");
            } else {
                printf("No\n");
                merge(x, y);  // 合并两个杯子所属的集合
            }
        }

        int count = 0;
        printf("%d\n", n);  // 输出杯子数量,初始假设所有杯子都有阔落
        for (i = 1; i <= n; i++) {
            if (parent[i] == i) {
                printf("%d ", i);  // 输出有阔落的杯子编号
                count++;
            }
        }
        printf("\n");
    }

    return 0;
}

在这个解决方案中,我们使用一个循环读取多组测试数据。

对于每组测试数据,我们首先读取杯子的数量n和操作次数m。

然后,我们创建一个大小为n的并查集数组parent,并将每个杯子初始化为属于自己的集合。

接下来,我们进行m次操作。对于每次操作,我们读取两个杯子的编号x和y。

如果x和y已经在同一个集合中(即它们属于同一杯阔落),则输出"Yes"。

如果x和y不在同一个集合中,我们将原始编号为y所在杯子的所有阔落倒入原始编号为x所在的杯子,并输出"No"。然后,我们将这两个杯子所属的集合合并。

完成m次操作后,我们统计有阔落的杯子数量,并输出这些杯子的编号。

综上所述,这个C语言程序可以根据输入的阔落杯子编号和操作,输出每次操作的结果以及最后有阔落的杯子数量和编号。

第4题:青蛙的约会

两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面。它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止。可是它们出发之前忘记了一件很重要的事情,既没有问清楚对方的特征,也没有约定见面的具体位置。不过青蛙们都是很乐观的,它们觉得只要一直朝着某个方向跳下去,总能碰到对方的。但是除非这两只青蛙在同一时间跳到同一点上,不然是永远都不可能碰面的。为了帮助这两只乐观的青蛙,你被要求写一个程序来判断这两只青蛙是否能够碰面,会在什么时候碰面。 我们把这两只青蛙分别叫做青蛙A和青蛙B,并且规定纬度线上东经0度处为原点,由东往西为正方向,单位长度1米,这样我们就得到了一条首尾相接的数轴。设青蛙A的出发点坐标是x,青蛙B的出发点坐标是y。青蛙A一次能跳m米,青蛙B一次能跳n米,两只青蛙跳一次所花费的时间相同。纬度线总长L米。现在要你求出它们跳了几次以后才会碰面。
时间限制:1000
内存限制:65536
输入
输入只包括一行5个整数x,y,m,n,L,其中x≠y < 2000000000,0 < m、n < 2000000000,0 < L < 2100000000。
输出
输出碰面所需要的跳跃次数,如果永远不可能碰面则输出一行"Impossible"
样例输入
1 2 3 4 5
样例输出
4

这个问题可以通过求解一元线性同余方程来解决。线性同余方程的一般形式为ax ≡ b (mod m),其中a、b、m为已知整数,x为未知数。在这个问题中,我们需要求解的是 (x + mt) ≡ (y + nt) (mod L),其中t为正整数,表示跳了多少次。

以下是一个解决"青蛙的约会"问题的C语言程序:

#include <stdio.h>

long long gcd(long long a, long long b) {
    if (b == 0) {
        return a;
    }
    return gcd(b, a % b);
}

int main() {
    long long x, y, m, n, L;
    scanf("%lld %lld %lld %lld %lld", &x, &y, &m, &n, &L);

    long long diff = y - x;
    long long lcm = m * n / gcd(m, n);

    if (diff % gcd(m, n) != 0) {
        printf("Impossible\n");
    } else {
        diff = (diff % L + L) % L;  // 防止diff为负数
        long long ans = diff / gcd(m, n) % (L / gcd(m, n));
        printf("%lld\n", ans);
    }

    return 0;
}

在这个解决方案中,我们首先读取输入的x、y、m、n和L。

我们计算出差值diff = y - x,并计算m和n的最小公倍数lcm = m * n / gcd(m, n)。

如果diff不是gcd(m, n)的倍数,则说明两只青蛙永远不会碰面,输出"Impossible"。

否则,我们将diff取模L,并确保结果为非负数。然后,我们计算答案ans = diff / gcd(m, n) % (L / gcd(m, n))。这里我们将结果除以gcd(m, n),以确保ans是最小非负整数。

最后,我们输出答案ans,表示两只青蛙碰面所需要的跳跃次数。

综上所述,这个C语言程序可以根据输入的参数,计算出两只青蛙碰面所需要的跳跃次数。如果永远不可能碰面,则输出"Impossible"。

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

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

相关文章

阿里云云主机免费试用三个月

试用链接如下&#xff1a; 阿里云云产品免费试用 云主机 费用试用三个月&#xff0c;每月750小时 实例规格 1核(vCPU) 2 GiB S6 系列机型 适用搭建网站等场景 网络带宽 1M 公网固定网络带宽 云盘40 GiB 真香&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&…

【经验分享】如何使用VSCode对比两个文件

问题&#xff1a; 当有两个不同版本的文件&#xff0c;如何使用VSCode对比两个文件 解决办法 长按ctrl选择想要对比的两个文件-----右键选择将已选项进行比较----大功告成 大功告成

Light Matrix、鲁比尼拳击场和 The Sandbox 联合推出鲁比尼拳击元宇宙

The Sandbox 非常高兴地宣布与 Light Matrix 以及鲁比尼拳击场达成战略合作。作为合作的一部分&#xff0c;The Sandbox、LightMatrix 和鲁比尼拳击场将共同创作「鲁比尼拳击场」&#xff0c;这是第一个在全球范围内展示泰拳艺术和泰拳故事的项目。该项目由 Demo Corporation 开…

算法:数组中的最大差值---“打擂台法“

1、题目&#xff1a; 给定一个整数数组 nums&#xff0c;找出给定数组中两个数字之间的最大差值。要求&#xff0c;第二个数字必须大于第一个数字。 2、分析特点&#xff1a; 求最大差值 > 最大值 - 最小值只需要遍历价格数组一遍&#xff0c;记录历史最小值&#xff0c;非…

DeepStream-gst-dsexample

gst-dsexample是个例子插件&#xff0c;你可以修改定制里的实现。你可以blur原图像&#xff0c;也可以填加新的meta. 变量解释 host_rgb_buf是根据用户设置的宽高processing_width/processing_height,创建的hostcuda内存&#xff0c;需要主要的是&#xff0c;它的格式RGB。 …

接口加密了该怎么测?

对明文编码生成信息摘要&#xff0c;以防止被篡改。比如MD5使用的是Hash算法&#xff0c;无论多长的输入&#xff0c;MD5都会输出长度为128bits的一个串。 摘要算法不要秘钥&#xff0c;客户端和服务端采用相同的摘要算法即可针对同一段明文获取一致的密文。 一、对称加密 对…

孙哥Spring源码第19集

第19集 refresh()-invokeBeanFactoryPostProcessor 三- Import三种形式的处理过程 【视频来源于&#xff1a;B站up主孙帅suns Spring源码视频】【微信号&#xff1a;suns45】 1、ImportBeanDefinitionRegister的处理过程 在processImports处理Import注解中 ImportBeanDefinit…

数据结构 - 双向链表

文章目录 目录 文章目录 前言 一、什么是双向链表? 双向链表有什么优势? 二、双向链表的设计和实现 1.设计思想 尾增 : 在链表的末尾添加新的元素 头插 : 在链表头部插入节点 删除 : 根据val的值删除节点 查找 : 根据索引的值查找并返回节点 总结 前言 大家好,今天给…

Window安装虚拟机+给虚拟机安装Linux

一、虚拟机下载 这里使用Virtualbox虚拟机。可以直接从官网下载&#xff1a;Downloads – Oracle VM VirtualBox 点击进行下载&#xff0c;选择window版本的。直接双击&#xff0c;一直下一步 进行安装 PS&#xff1a;安装需要开启CPU虚拟化&#xff0c;一般电脑都已经开启了…

【大麦小米学量化】使用天勤TqSdk实现期货量化交易(入门)

文章目录 酱香拿铁的故事一、TqSdk 是什么&#xff1f;二、准备工作1. 安装tqsdk库&#xff08;Python环境提前准备好&#xff09;2. 注册快期账户3. 支持的期货公司&#xff08;更新以官方公布为准&#xff09; 三、初试牛刀1. 示例代码&#xff1a;2. 运行后提示如下&#xf…

VIT中的einops包详解

‘’‘einops有三个常用方法&#xff1a;rearrange,repeat,reduce’‘’ rearrange的操作相当于转置 rearrange(image,‘h w c -> w h c’) 高和宽转置 path ../data/cat_and_mouse.jpg image cv2.imread(path) h,w,c image.shape # shape第一个值是h,第二个是w image…

Vue框架--Vue列表渲染(1)

1.列表的基本遍历 Vue提供了v-for用于遍历数据内容,我们在这里重点说两种数据的遍历:数组的遍历和对象的遍历。遍历数组对象如下所示: 遍历对象案例:

vue3项目部署报错 Faled to esolve entry for pacdlage “hntlify/sthared“

版本 vue 3.2.47 vue-i18n 9.2.2 本地运行没有问题&#xff0c;jenkins上部署报错找不到"hntlify/sthared"包 排查问题&#xff1a; 查看vue-i18n官网&#xff0c;发现有引用到这个包 “hntlify/sthared” vue-i18n最新版本是9.3.0&#xff0c;未锁定版本&#xf…

Excel 将数字添加百分号

目的&#xff1a;将56.33变成56.33% 打一个“100”&#xff0c;然后ctrlc复制 全选要操作的数据&#xff0c;右键&#xff0c;选择“选择性张贴” 选择“除” 再选择“百分比” 可以调整位数 软件工程小施同学 20230907

【0907 C高级day2】Shell脚本

一、作业&#xff1a;写一个shell脚本&#xff0c;将以下内容放到脚本中 在家目录下创建目录文件&#xff0c;dir在dir下创建dir1和dir2把当前目录下的所有文件拷贝到dir1中&#xff0c;把当前目录下的所有脚本文件拷贝到dir2中把dir2打包并压缩为dir2.tar.xz再把dir2.tar.xz移…

Mac上的视频管理神器:MetaVideo for Mac让你的视频搜索和整理更轻松

视频时代已经来临&#xff0c;我们每天都会接触到各种各样的视频资源。但是&#xff0c;如何管理和编辑这些视频文件&#xff0c;让它们更加易于查找和使用呢&#xff1f;MetaVideo for Mac可以帮助你解决这个问题。 MetaVideo for Mac是一款专门为Mac用户设计的视频管理软件&…

2023京东医疗保健器械行业数据分析(京东数据分析平台)

随着人们对自身健康的重视程度不断加深&#xff0c;当前市场中各类对疾病具有诊断、预防、监护、治疗或者缓解的医疗保健仪器越来越受到消费者的关注。 根据鲸参谋电商数据分析平台的相关数据显示&#xff0c;今年7月份&#xff0c;京东平台医疗保健仪器的销量为950万&#xf…

Java“牵手”1688商品详情数据,1688商品详情API接口,1688API接口申请指南

1688平台商品详情接口是开放平台提供的一种API接口&#xff0c;通过调用API接口&#xff0c;开发者可以获取1688商品的标题、价格、库存、月销量、总销量、库存、详情描述、图片等详细信息 。 获取商品详情接口API是一种用于获取电商平台上商品详情数据的接口&#xff0c;通过…

【广州华锐互动】VR景区云游:打造沉浸式网上虚拟旅游体验

VR景区云游体验是一种全新的旅游体验方式&#xff0c;通过虚拟现实技术&#xff0c;让游客在家中就能身临其境地游览各大景区。这种展示方式不仅节省了游客的时间和金钱&#xff0c;还能让他们在未出发前就对景区有更深入的了解。 通过虚拟现实技术&#xff0c;用户可以在景区内…