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

news2024/10/5 17:18:28

在这里插入图片描述

第1题:公共子序列

我们称序列Z = < z1, z2, …, zk >是序列X = < x1, x2, …, xm >的子序列当且仅当存在 严格上升 的序列< i1, i2, …, ik >,使得对j = 1, 2, … ,k, 有xij = zj。比如Z = < a, b, f, c > 是X = < a, b, c, f, b, c >的子序列。 现在给出两个序列X和Y,你的任务是找到X和Y的最大公共子序列,也就是说要找到一个最长的序列Z,使得Z既是X的子序列也是Y的子序列。
时间限制:3000
内存限制:65536
输入
输入包括多组测试数据。每组数据包括一行,给出两个长度不超过200的字符串,表示两个序列。两个字符串之间由若干个空格隔开。
输出
对每组输入数据,输出一行,给出两个序列的最大公共子序列的长度。
样例输入
abcfbc abfcab
programming contest
abcd mnp
样例输出
4
2
0

要解决最大公共子序列问题,可以使用动态规划的方法。

以下是使用C语言实现的代码:

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

#define MAX_LENGTH 200

int max(int a, int b) {
    return (a > b) ? a : b;
}

int longestCommonSubsequence(char X[], char Y[], int m, int n) {
    int dp[MAX_LENGTH + 1][MAX_LENGTH + 1];

    for (int i = 0; i <= m; i++) {
        for (int j = 0; j <= n; j++) {
            if (i == 0 || j == 0) {
                dp[i][j] = 0;
            } else if (X[i - 1] == Y[j - 1]) {
                dp[i][j] = dp[i - 1][j - 1] + 1;
            } else {
                dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
            }
        }
    }

    return dp[m][n];
}

int main() {
    char X[MAX_LENGTH + 1];
    char Y[MAX_LENGTH + 1];

    while (scanf("%s %s", X, Y) != EOF) {
        int m = strlen(X);
        int n = strlen(Y);

        int length = longestCommonSubsequence(X, Y, m, n);
        printf("%d\n", length);
    }

    return 0;
}

该代码使用一个二维数组dp来保存状态,其中dp[i][j]表示序列X的前i个字符和序列Y的前j个字符的最大公共子序列的长度。

首先,将dp[i][0]和dp[0][j]都设置为0,表示当一个序列的长度为0时,最大公共子序列的长度为0。

然后,从1到m和1到n的循环遍历,如果X[i-1]等于Y[j-1],则说明X的第i个字符和Y的第j个字符相同,将dp[i][j]设置为dp[i-1][j-1]的值加1,表示当前字符可以加入最大公共子序列。

如果X[i-1]不等于Y[j-1],则说明X的第i个字符和Y的第j个字符不相同,需要在X的前i-1个字符和Y的前j个字符的最大公共子序列和X的前i个字符和Y的前j-1个字符的最大公共子序列之间取最大值,即dp[i-1][j]和dp[i][j-1]的最大值。

最后,dp[m][n]即为X和Y的最大公共子序列的长度。

第2题:硬币问题

有N(不大于100)种硬币,编号为1至N,已知每种硬币的重量(不超过100的正整数)和面额(不超过100的正整数),每种硬币数量不限。选取总重量不超过C(不大于1000的正整数)的硬币,最多能获得多少总面额?
时间限制:1000
内存限制:65536
输入
第一行输入N 第二行输入C 第三行输入各硬币重量,用空格隔开 第四行输入各硬币价值,用空格隔开
输出
最大总面额
样例输入
3
5
1 2 5
1 3 6
样例输出
7

要解决硬币问题,可以使用动态规划的方法。

以下是使用C语言实现的代码:

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

#define MAX_COINS 100
#define MAX_WEIGHT 1000

int max(int a, int b) {
    return (a > b) ? a : b;
}

int maxTotalValue(int coins[], int values[], int n, int capacity) {
    int dp[MAX_WEIGHT + 1];
    memset(dp, 0, sizeof(dp));

    for (int i = 0; i < n; i++) {
        for (int j = coins[i]; j <= capacity; j++) {
            dp[j] = max(dp[j], dp[j - coins[i]] + values[i]);
        }
    }

    return dp[capacity];
}

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

    int capacity;
    scanf("%d", &capacity);

    int coins[MAX_COINS];
    int values[MAX_COINS];

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

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

    int maxTotal = maxTotalValue(coins, values, n, capacity);
    printf("%d\n", maxTotal);

    return 0;
}

该代码使用一个一维数组dp来保存状态,其中dp[j]表示总重量为j时的最大总面额。

首先,将dp数组初始化为0。

然后,从第一种硬币到第N种硬币的循环遍历,对于每种硬币,从其重量coins[i]开始,到总重量C为止的范围内,更新dp[j]的值。更新方式为取dp[j]和dp[j - coins[i]] + values[i]的最大值,表示在总重量为j时,可以选择不放入当前硬币(即dp[j]的值)或放入当前硬币(总重量减去当前硬币重量的最大总面额,再加上当前硬币的面额)。

最后,dp[capacity]即为总重量不超过C时的最大总面额。

第3题:田忌赛马

你一定听过田忌赛马的故事吧?
如果3匹马变成1000匹,齐王仍然让他的马按从优到劣的顺序出赛,田忌可以按任意顺序选择他的赛马出赛。赢一局,田忌可以得到200两银子,输一局,田忌就要输掉200两银子,平局的话不输不赢。
请问田忌最多能赢多少银子?
时间限制:5000
内存限制:65536
输入
输入包含多组测试数据. 每组测试数据的第一行是一个整数n(1<=n<=1000),表示田忌和齐王都拥有n匹马。接下来一行是n个整数,表示田忌的马的速度,下一行也是n个整数,表示齐王的马的速度。 输入的最后以一个0表示结束。
输出
对每组数据,输出一个整数,表示田忌至多可以赢多少银子,如果田忌赢不了,就输出一个负数,表示田忌最少要输多少银子。
样例输入
3
92 83 71
95 87 74
2
20 20
20 20
2
20 19
22 18
0
样例输出
200
0
0

要解决田忌赛马问题,可以使用贪心算法的思想。

以下是使用C语言实现的代码:

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

int compare(const void *a, const void *b) {
    return *(int *)b - *(int *)a;
}

int calculateMaximumSilver(int tianjiHorses[], int qiwangHorses[], int n) {
    int maxSilver = 0;
    qsort(tianjiHorses, n, sizeof(int), compare);
    qsort(qiwangHorses, n, sizeof(int), compare);

    int tianjiIndex = 0;
    int qiwangIndex = 0;

    while (tianjiIndex < n && qiwangIndex < n) {
        if (tianjiHorses[tianjiIndex] > qiwangHorses[qiwangIndex]) {
            maxSilver += 200;
            tianjiIndex++;
            qiwangIndex++;
        } else if (tianjiHorses[tianjiIndex] < qiwangHorses[qiwangIndex]) {
            tianjiIndex++;
        } else {
            qiwangIndex++;
        }
    }

    if (qiwangIndex == n) {
        return maxSilver - 200 * (n - tianjiIndex);
    } else {
        return -maxSilver;
    }
}

int main() {
    int n;
    while (scanf("%d", &n) == 1 && n != 0) {
        int tianjiHorses[1000];
        int qiwangHorses[1000];

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

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

        int maxSilver = calculateMaximumSilver(tianjiHorses, qiwangHorses, n);
        printf("%d\n", maxSilver);
    }

    return 0;
}

该代码首先使用qsort函数对田忌和齐王的马的速度进行降序排序。

然后,使用两个指针tianjiIndexqiwangIndex来遍历田忌和齐王的马的速度数组。

在每一轮比赛中,如果田忌的马速度大于齐王的马速度,则田忌赢得这局比赛,将最大银子数增加200,并将两个指针都向后移动一位。

如果田忌的马速度小于齐王的马速度,则田忌输掉这局比赛,将田忌的指针向后移动一位。

如果田忌的马速度等于齐王的马速度,则平局,将两个指针都向后移动一位。

最后,如果田忌的指针tianjiIndex达到了数组长度n,说明田忌赢得了所有比赛,返回最大银子数;如果齐王的指针qiwangIndex达到了数组长度n,说明田忌输掉了所有比赛,返回负的最大银子数。

第4题:上机

又到周末了,同学们陆陆续续开开心心的来到机房上机。jbr也不例外,但是他到的有点晚,发现有些机位上已经有同学正在做题,有些机位还空着。细心的jbr发现,一位同学来到机房,坐在机位i上,如果他的左右两边都空着,他将获得能力值a[i];如果当他坐下时,左边或者右边已经有一个人在上机了,他将获得能力值b[i];如果当他坐下时,他的左边右边都有人在上机,他将获得能力值c[i]。
同时他发现,已经在上机的同学不会受到刚要坐下的同学的影响,即他们的能力值只会在坐下时产生,以后不会发生变化;第一个机位左边没有机位,最后一个机位右边没有机位,无论何时坐在这两个机位上将无法获得c值。
这时jbr发现有一排机器还空着,一共有N个机位,编号1到N。这时有N位同学们陆陆续续来到机房,一个一个按照顺序坐在这排机位上。聪明的jbr想知道怎么安排座位的顺序,可以使这N位同学获得能力值的和最大呢?
时间限制:1000
内存限制:65536
输入
第一行一个整数N(1<= N <= 10000)
第二行N个数,表示a[i]
第三行N个数,表示b[i]
第四行N个数,表示c[i]
(1<= a[i],b[i],c[i] <=10000)
输出
一个整数,表示获得最大的能力值和
样例输入
4
1 2 2 4
4 3 3 1
2 1 1 2
样例输出
14
提示
第一位同学坐在第四个机位上,获得能力值4; 第二位同学坐在第三个机位上,获得能力值3; 第三位同学坐在第二个机位上,获得能力值3; 第四位同学坐在第一个机位上,获得能力值4; 总和为14。

要解决座位安排的问题,可以使用动态规划的方法。

以下是使用C语言实现的代码:

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

int max(int a, int b) {
    return (a > b) ? a : b;
}

int calculateMaxAbility(int a[], int b[], int c[], int n) {
    int dp[3][10001] = {0};

    dp[0][1] = a[1];
    dp[1][1] = b[1];
    dp[2][1] = 0;

    for (int i = 2; i <= n; i++) {
        dp[0][i] = max(dp[1][i - 1], dp[2][i - 1]) + a[i];
        dp[1][i] = max(dp[0][i - 1], dp[2][i - 1]) + b[i];
        dp[2][i] = max(dp[0][i - 1], dp[1][i - 1]) + c[i];
    }

    return max(max(dp[0][n], dp[1][n]), dp[2][n]);
}

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

    int a[10001];
    int b[10001];
    int c[10001];

    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
    }

    for (int i = 1; i <= n; i++) {
        scanf("%d", &b[i]);
    }

    for (int i = 1; i <= n; i++) {
        scanf("%d", &c[i]);
    }

    int maxAbility = calculateMaxAbility(a, b, c, n);
    printf("%d\n", maxAbility);

    return 0;
}

该代码使用一个二维数组dp来记录每个位置上的能力值。dp[i][j]表示第j个机位上的同学选择第i种能力值时的最大能力值和。

初始化时,将第一个机位上的能力值分别赋值给dp[0][1]dp[1][1]dp[2][1]

然后,从第二个机位开始,利用动态规划的思想,根据题目给出的能力值计算出每个位置上三种情况的最大能力值和。

最后,返回dp数组中最后一列的最大值,即为获得最大的能力值和。

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

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

相关文章

软考:中级软件设计师:关系代数:中级软件设计师:关系代数,规范化理论函数依赖,它的价值和用途,键,范式,模式分解

软考&#xff1a;中级软件设计师:关系代数 提示&#xff1a;系列被面试官问的问题&#xff0c;我自己当时不会&#xff0c;所以下来自己复盘一下&#xff0c;认真学习和总结&#xff0c;以应对未来更多的可能性 关于互联网大厂的笔试面试&#xff0c;都是需要细心准备的 &…

一篇文章带你彻底了解Java常用的设计模式

文章目录 前言1. 工厂模式使用示例代码优势 2. 单例模式说明使用示例代码优势 3. 原型模式使用示例代码优势 4. 适配器模式使用示例代码优势 5. 观察者模式使用示例代码优势 6. 策略模式使用示例代码优势 7. 装饰者模式使用示例代码优势 8. 模板方法模式使用示例代码优势 总结 …

python-数据可视化-下载数据-CSV文件格式

数据以两种常见格式存储&#xff1a;CSV和JSON CSV文件格式 comma-separated values import csv filename sitka_weather_07-2018_simple.csv with open(filename) as f:reader csv.reader(f)header_row next(reader)print(header_row) # [USW00025333, SITKA AIRPORT, A…

YOLO目标检测——皮肤检测数据集下载分享

数据集点击下载&#xff1a;YOLO皮肤检测数据集Face-Dataset.rar

springboot源码方法

利用LinkedHashSet移除List重复的数据protected final <T> List<T> removeDuplicates(List<T> list) {return new ArrayList<>(new LinkedHashSet<>(list));} SpringFactoriesLoader#loadFactoryNames 加载配置文件

常见的移动端布局

流式布局&#xff08;百分比布局&#xff09; 使用百分比、相对单位&#xff08;如 em、rem&#xff09;等来设置元素的宽度&#xff0c;使页面元素根据视口大小的变化进行调整。这种方法可以实现基本的自适应效果&#xff0c;但可能在不同设备上显示不一致。 <!DOCTYPE ht…

ctfshow-web14

0x00 前言 CTF 加解密合集CTF Web合集 0x01 题目 0x02 Write Up 首先看到这个&#xff0c;swith&#xff0c;那么直接输入4&#xff0c;则会打印$url的值 然后访问一下 查看一下&#xff0c;发现完整的请求是http://c7ff9ed6-dccd-4d01-907a-f1c61c016c15.challenge.ctf.sho…

python网络爬虫指南二:多线程网络爬虫、动态内容爬取(待续)

文章目录 一、多线程网络爬虫1.1 线程的基础内容、GIL1.2 创建线程的两种方式1.3 threading.Thread类1.4 线程常用方法和锁机制1.5 生产者-消费者模式1.5.1 生产者-消费者模式简介1.5.2 Condition 类协调线程 1.6 线程中的安全队列1.6 多线程爬取王者荣耀壁纸1.6.1 网页分析1.6…

2023-8-26 模拟散列表

题目链接&#xff1a;模拟散列表 拉链法 #include <iostream> #include <cstring>using namespace std;const int N 100010;int h[N], e[N], ne[N], idx;void insert(int x) {int k (x % N N) % N;e[idx] x;ne[idx] h[k];h[k] idx;idx ; }bool query(int …

智慧县城,乍暖还寒风起时

提起中国的区域数字化&#xff0c;我们大概率会关注两个维度。一个是北上广深为代表的超大城市&#xff0c;这里的智慧城市落地是风向标、排头兵&#xff1b;另一个是乡村的数字化、智能化&#xff0c;作为区域智能升级的最小单位&#xff0c;乡村的典型性更强&#xff0c;也符…

nlp大模型课程笔记

自然语言处理基础和应用 &#x1f446;说明之前的大模型其实有很多都是基于迁移学习的方法。 attention机制的总结&#xff0c;解决了信息瓶颈的问题。 处理词组时BPE的过程 &#x1f446;pos表示的是token所在的位置 &#x1f446;技巧是layer normalization。

数据结构(Java实现)-二叉树(上)

树型结构 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上&#xff0c;而叶朝下的。 有一个特殊的结点&#xff0c;称为根结点&…

从爬楼梯到斐波那契数列:解密数学之美

题目描述 我们来看看力扣的一道经典问题70. 爬楼梯 递归 假设n级台阶有climbStairs(n)种方法爬到楼梯顶。如果有n级台阶&#xff0c;如果第一次往上爬1级台阶&#xff0c;就会剩下n-1级台阶&#xff0c;这n-1级台阶就有climbStairs(n-1)种方法爬到楼梯顶&#xff1b;如果第一…

C++通过JNI调用JAVA方法返回ArrayList对象

运行效果: JAVA实现: 获取系统已安装应用列表并返回List<String>对象 //使用系统API获取安装包列表public List<String> getAppList(MainActivity act) {List<String> packages = new ArrayList<String>();try {//取包信息列表List<PackageInf…

Python学习 -- 类的多态

在面向对象编程中&#xff0c;多态性是一项强大的特性&#xff0c;它允许不同的对象对同一方法产生不同的行为。Python作为一门面向对象的编程语言&#xff0c;也支持多态性。本篇博客将深入探讨Python中的类多态性&#xff0c;通过详细的代码案例来展示其灵活性和可扩展性。 …

Leetcode 2235.两整数相加

一、两整数相加 给你两个整数 num1 和 num2&#xff0c;返回这两个整数的和。 示例 1&#xff1a; 输入&#xff1a;num1 12, num2 5 输出&#xff1a;17 解释&#xff1a;num1 是 12&#xff0c;num2 是 5 &#xff0c;它们的和是 12 5 17 &#xff0c;因此返回 17 。示例…

2023.8 -java - 继承

继承就是子类继承父类的特征和行为&#xff0c;使得子类对象&#xff08;实例&#xff09;具有父类的实例域和方法&#xff0c;或子类从父类继承方法&#xff0c;使得子类具有父类相同的行为。 继承的特性 子类拥有父类非 private 的属性、方法。 子类可以拥有自己的属性和方法…

API Gateway介绍

使用微服务架构开发应用后&#xff0c;每个微服务都将拥有自己的API&#xff0c;设计应用外部API的任务因客户端的多样性而变得更具有挑战性。不同客户端通常需要不同的数据。通常基于PC浏览器的用户界面显示的信息要远多于移动设备的用户界面。此外&#xff0c;不同的客户端通…

基于Java+SpringBoot+Vue前后端分离公交线路查询系统设计和实现

博主介绍&#xff1a;✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专…

Android学习之路(9) Bundle

Bundle的概念理解 Bundle经常出现在以下场合&#xff1a; Activity状态数据的保存与恢复涉及到的两个回调&#xff1a;void onSaveInstanceState (Bundle outState)、void onCreate (Bundle savedInstanceState)Fragment的setArguments方法&#xff1a;void setArguments (Bu…