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

在这里插入图片描述

第1题:问题求解

给定一个正整数N,求最小的M满足比N大且M与N的二进制表示中有相同数目的1。
举个例子,假如给定N为78,二进制表示为1001110,包含4个1,那么最小的比N大的并且二进制表示中只包含4个1的数是83,其二进制是1010011,因此83就是答案。
时间限制:1000
内存限制:65536
输入
输入若干行,每行一个数N(1 ≤ N ≤ 1000000),如果这行为0表示输入结束。
输出
对于每个N,输出对应的M。
样例输入
1
2
3
4
78
0
样例输出
2
4
5
8
83

这个问题可以使用搜索剪枝技术来解决。我们可以从给定的整数N开始,逐个尝试比N大的整数,直到找到一个满足条件的整数M。在每次尝试时,我们需要判断M的二进制表示中是否包含与N相同数量的1。如果找到了满足条件的M,则输出M作为答案。

下面是一个使用搜索剪枝技术的示例代码:

#include <stdio.h>

// 计算一个整数的二进制表示中1的数量
int countOnes(int num) {
    int count = 0;
    while (num) {
        count += num & 1;
        num >>= 1;
    }
    return count;
}

// 判断一个整数的二进制表示中1的数量是否与给定的count相等
int hasSameNumberOfOnes(int num, int count) {
    return countOnes(num) == count;
}

// 搜索比N大且二进制表示中包含count个1的整数
int findNextNumber(int N, int count) {
    int num = N + 1;
    while (!hasSameNumberOfOnes(num, count)) {
        num++;
    }
    return num;
}

int main() {
    int N;
    while (scanf("%d", &N) == 1 && N != 0) {
        int count = countOnes(N);
        int M = findNextNumber(N, count);
        printf("%d\n", M);
    }
    return 0;
}

这段代码定义了三个函数:countOnes用于计算一个整数的二进制表示中1的数量,hasSameNumberOfOnes用于判断一个整数的二进制表示中1的数量是否与给定的count相等,findNextNumber用于搜索比N大且二进制表示中包含count个1的整数。

main函数中,首先读取输入的整数N,然后通过调用countOnes函数计算N的二进制表示中1的数量。接下来,调用findNextNumber函数找到比N大且二进制表示中包含相同数量的1的整数M。最后,输出M作为答案。

你可以将题目给出的示例输入复制到代码中进行测试。

第2题:算24

给出4个小于10个正整数,你可以使用加减乘除4种运算以及括号把这4个数连接起来得到一个表达式。现在的问题是,是否存在一种方式使得得到的表达式的结果等于24。 这里加减乘除以及括号的运算结果和运算的优先级跟我们平常的定义一致(这里的除法定义是实数除法)。 比如,对于5,5,5,1,我们知道5 * (5 – 1 / 5) = 24,因此可以得到24。又比如,对于1,1,4,2,我们怎么都不能得到24。
时间限制:6000
内存限制:65536
输入
输入数据包括多行,每行给出一组测试数据,包括4个小于10个正整数。最后一组测试数据中包括4个0,表示输入的结束,这组数据不用处理。
输出
对于每一组测试数据,输出一行,如果可以得到24,输出“YES”;否则,输出“NO”。
样例输入
5 5 5 1
1 1 4 2
0 0 0 0
样例输出
YES
NO

这个问题可以使用搜索剪枝技术来解决。我们可以尝试对给定的4个数字进行各种运算和排列组合,判断是否存在一种方式使得表达式的结果等于24。在每次尝试时,我们可以使用递归来遍历所有可能的运算和数字排列,并进行剪枝操作以提高效率。

下面是一个使用搜索剪枝技术的示例代码:

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

#define TARGET 24
#define EPSILON 1e-6

bool canGet24(double nums[], int count) {
    if (count == 1) {
        return fabs(nums[0] - TARGET) < EPSILON;
    }

    for (int i = 0; i < count; i++) {
        for (int j = 0; j < count; j++) {
            if (i == j) {
                continue;
            }

            double a = nums[i];
            double b = nums[j];

            double nextNums[count - 1];
            int nextCount = 0;

            for (int k = 0; k < count; k++) {
                if (k != i && k != j) {
                    nextNums[nextCount++] = nums[k];
                }
            }

            nextNums[nextCount] = a + b;
            if (canGet24(nextNums, nextCount + 1)) {
                return true;
            }

            nextNums[nextCount] = a - b;
            if (canGet24(nextNums, nextCount + 1)) {
                return true;
            }

            nextNums[nextCount] = b - a;
            if (canGet24(nextNums, nextCount + 1)) {
                return true;
            }

            nextNums[nextCount] = a * b;
            if (canGet24(nextNums, nextCount + 1)) {
                return true;
            }

            if (b != 0) {
                nextNums[nextCount] = a / b;
                if (canGet24(nextNums, nextCount + 1)) {
                    return true;
                }
            }

            if (a != 0) {
                nextNums[nextCount] = b / a;
                if (canGet24(nextNums, nextCount + 1)) {
                    return true;
                }
            }
        }
    }

    return false;
}

int main() {
    double nums[4];
    while (scanf("%lf %lf %lf %lf", &nums[0], &nums[1], &nums[2], &nums[3]) == 4) {
        if (nums[0] == 0 && nums[1] == 0 && nums[2] == 0 && nums[3] == 0) {
            break;
        }

        if (canGet24(nums, 4)) {
            printf("YES\n");
        } else {
            printf("NO\n");
        }
    }

    return 0;
}

这段代码定义了一个canGet24函数,用于判断给定的4个数字是否可以通过运算得到24。在函数内部,使用两层循环遍历所有可能的数字组合,并针对每个组合进行各种运算操作。在每次运算后,将得到的结果与24进行比较,如果结果接近24(使用浮点数比较,并定义了一个极小的误差范围EPSILON),则递归调用canGet24函数继续判断剩余的数字是否可以得到24。如果最终找到一种方式使得结果等于24,返回true;否则,返回false

main函数中,首先读取输入的4个数字,然后通过调用canGet24函数判断是否可以得到24,并输出相应的结果。

你可以将题目给出的示例输入复制到代码中进行测试。

第3题:忍者道具

忍者道具有很多种,苦无,飞镖,震爆弹。L君热衷于收集忍者道具,现在他有N个道具,每个道具的重量分别是C1、C2…CN。现在他想把这N个道具装到载重量为W的工具包里,请问他最少需要多少个工具包?
时间限制:1000
内存限制:65536
输入
第一行包含两个用空格隔开的整数,N和W。 接下来N行每行一个整数,其中第i+1行的整数表示第i个道具的重量Ci。
输出
输出一个整数,最少需要多少个工具包。
样例输入
5 1996
1
2
1994
12
29
样例输出
2
提示
对于100%的数据,1<=N<=18,1<=Ci<=W<=10^8。

这个问题可以使用贪心算法来解决。我们可以按照道具的重量从大到小进行排序,然后依次将道具放入工具包中,直到当前道具无法放入为止。然后再取下一个道具放入工具包,重复这个过程,直到所有道具都被放入工具包中。最后统计使用的工具包数量即可。

下面是一个使用贪心算法的示例代码:

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

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

int minToolkits(int weights[], int N, int W) {
    qsort(weights, N, sizeof(int), compare); // 按照重量从大到小排序

    int count = 0; // 工具包数量
    int currentWeight = 0; // 当前工具包中的总重量

    for (int i = 0; i < N; i++) {
        if (currentWeight + weights[i] > W) {
            // 当前道具无法放入当前工具包,需要使用新的工具包
            count++;
            currentWeight = 0;
        }

        currentWeight += weights[i];
    }

    // 最后一个工具包可能未达到最大载重,但仍然需要计算在内
    if (currentWeight > 0) {
        count++;
    }

    return count;
}

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

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

    int result = minToolkits(weights, N, W);
    printf("%d\n", result);

    return 0;
}

这段代码定义了一个minToolkits函数,用于计算最少需要多少个工具包来装载道具。在函数内部,首先使用qsort函数对道具的重量进行排序,按照从大到小的顺序。然后,使用贪心策略,依次将道具放入工具包中,如果当前道具无法放入当前工具包,则使用新的工具包。最后,统计使用的工具包数量并返回。

main函数中,首先读取输入的N和W,然后读取每个道具的重量,并将它们存储在weights数组中。接下来,调用minToolkits函数计算最少需要的工具包数量,并输出结果。

你可以将题目给出的示例输入复制到代码中进行测试。

第4题:泳池

小C在一个排水系统不太好的学校上学。又是一个下雨天,学校里高低不平积了很多水。小C突发奇想:如果大雨一直下,多久以后我可以在学校里游泳呢?
学校是 N x N 的坐标方格 grid 中,每一个方格的值 grid(i,j)表示在位置 (i,j) 的高度。现在开始下雨了。当时间为 t 时,此时雨水导致方格中任意位置的水位为 t 。你可以从一个方格游向四周相邻的任意一个方格,但是前提是此时水位必须同时淹没这两个方格。假定小C的游动是不耗时的。
现在小C从坐标方格的左上(0,0)出发。最少耗时多久他才能到达坐标方格的右下平台 (N-1, N-1)?
时间限制:1000
内存限制:65536
输入
第一行有一个整数N,以下是一个N*N的方阵,代表各处的高度。 输入范围: 2 ≤ N ≤ 300 0 ≤ Height ≤ 10000000
输出
输出一个整数,代表最少等待时间T
样例输入
样例输入1:
2
0 2
1 3
样例输入2:
5
0 1 2 3 4
24 23 22 21 5
12 13 14 15 16
11 17 18 19 20
10 9 8 7 6
样例输出
样例输出1:
3
样例输出2:
16
提示
样例1:时间为3时,才可以游向平台(1,1),此时水位为3。 样例2:时间为16时,水位为16,此时才能保证(0,0)和(4,4)是联通的(请自行找出一条通路)。

这个问题可以使用搜索剪枝技术来解决。我们可以使用深度优先搜索(DFS)来搜索所有可能的路径,并在搜索过程中进行剪枝,以减少搜索空间。

下面是一个使用搜索剪枝技术的示例代码:

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

#define MAX_N 300

int N;
int grid[MAX_N][MAX_N];
int visited[MAX_N][MAX_N];

int minTime(int x, int y, int t) {
    if (x == N - 1 && y == N - 1) {
        return t;
    }

    visited[x][y] = 1;

    int min = -1;

    // 搜索上方
    if (x > 0 && !visited[x - 1][y] && grid[x - 1][y] >= t) {
        int time = minTime(x - 1, y, t + 1);
        if (time != -1 && (min == -1 || time < min)) {
            min = time;
        }
    }

    // 搜索下方
    if (x < N - 1 && !visited[x + 1][y] && grid[x + 1][y] >= t) {
        int time = minTime(x + 1, y, t + 1);
        if (time != -1 && (min == -1 || time < min)) {
            min = time;
        }
    }

    // 搜索左边
    if (y > 0 && !visited[x][y - 1] && grid[x][y - 1] >= t) {
        int time = minTime(x, y - 1, t + 1);
        if (time != -1 && (min == -1 || time < min)) {
            min = time;
        }
    }

    // 搜索右边
    if (y < N - 1 && !visited[x][y + 1] && grid[x][y + 1] >= t) {
        int time = minTime(x, y + 1, t + 1);
        if (time != -1 && (min == -1 || time < min)) {
            min = time;
        }
    }

    visited[x][y] = 0;

    return min;
}

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

    for (int i = 0; i < N; i++) {
        for (int j = 0; j < N; j++) {
            scanf("%d", &grid[i][j]);
            visited[i][j] = 0;
        }
    }

    int result = minTime(0, 0, 0);
    printf("%d\n", result);

    return 0;
}

这段代码定义了一个minTime函数,用于计算小C到达右下平台的最少等待时间。在函数内部,我们使用深度优先搜索(DFS)来搜索所有可能的路径。对于每个位置(x, y),我们判断是否可以从当前位置游向上、下、左、右四个方向,并将其未访问过且高度不低于当前时间的位置加入搜索路径中。递归地搜索下去,直到到达右下平台或者无法继续搜索。如果找到一条路径,我们记录下最小的等待时间。在搜索过程中,使用visited数组来标记已经访问过的位置,避免重复访问。

main函数中,首先读取输入的N和每个方格的高度,并将它们存储在grid数组中。然后,调用minTime函数计算最少等待时间,并输出结果。

你可以将题目给出的示例输入复制到代码中进行测试。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何更好的设计测试用例

测试用例设计的最基本要求&#xff1a;覆盖住所要测试的功能。这是再基本不过的要求了&#xff0c;但别看只是简单的一句话&#xff0c;要能够达到切实覆盖全面&#xff0c;需要对被测试产品功能的全面了解、明确测试范围(特别是要明确哪些是不需要测试的)、具备基本的测试技术…

【爬虫】实验项目二:模拟登录和数据持久化

目录 一、实验目的 二、实验预习提示 三、实验内容 实验要求 基本要求&#xff1a; 改进要求A&#xff1a; 改进要求B&#xff1a; 四、实验过程 基本要求&#xff1a; 源码如下&#xff1a; 改进要求A: 源码如下&#xff1a; 改进要求B&#xff1a; 源码如下&…

图像扭曲之万花筒

源码&#xff1a; void kaleidoscope(cv::Mat& src,cv::Mat& dst,double angle,double radius) {dst.create(src.rows, src.cols, CV_8UC3);dst.setTo(0);int cx src.cols / 2;int cy src.rows / 2;//angle PI / 4;double angle2 PI / 4;double sides radius / 3…

C++面试题(叁)---操作系统篇

目录 操作系统篇 1 Linux中查看进程运行状态的指令、查看内存使用情况的指令、 tar解压文件的参数。 2 文件权限怎么修改 3 说说常用的Linux命令 4 说说如何以root权限运行某个程序。 5 说说软链接和硬链接的区别。 6 说说静态库和动态库怎么制作及如何使用&#xff0c;区…

【网络安全防护】上海道宁与Bitdefender帮助您构建弹性网络并降低安全运营成本

在网络的世界中 风险变得更加常见与复杂 企业需要从网络安全转向网络弹性 复杂的网络攻击已非常普遍 在面临攻击时 企业如何保持业务连续性&#xff1f; Bitdefender GravityZone将 风险分析、安全加固、威胁预防 检测和响应功能相结合 帮助您构建弹性网络 并降低安全…

windows下Mysql安装配置教程

Mysql下载 在官网下载mysql community Server https://dev.mysql.com/downloads/mysql/ 可以选择下载压缩包或者MSI安装程序 使用压缩包安装 MySQL 压缩包安装通常需要以下步骤&#xff1a; 1. 下载 MySQL 安装包 你可以从 MySQL 官网上下载适合你系统的 MySQL 安装包&am…

基于PIC单片机温度-脉搏-DS18B20温度-液晶12864显示(proteus仿真+源程序)

一、系统方案 1、上电初始化液晶第一行显示脉搏&#xff0c;第二行显示温度&#xff0c;第三行显示模式&#xff0c;第四行显示强度&#xff1b;按下K1按键可以选择模式&#xff0c;催眼模式或治疗模式。 2、治疗模块下&#xff0c;可以通过K2、K3修改强度。 二、硬件设计 原理…

Day5:react函数组件与类组件

「目标」: 持续输出&#xff01;每日分享关于web前端常见知识、面试题、性能优化、新技术等方面的内容。 「主要面向群体&#xff1a;」前端开发工程师&#xff08;初、中、高级&#xff09;、应届、转行、培训、自学等同学 Day4-今日话题 react「函数组件和类组件」的区别&…

Spring-5.0.x源码下载及本地环境搭建

一、Spring源码下载 从github上下载Spring的源代码 下载地址&#xff1a;https://github.com/spring-projects/spring-framework 访问地址之后&#xff0c;打开Spring的代码页面找到你想下载的版本&#xff0c;如5.0.x&#xff0c;如下图所示&#xff1a; 下载方式一&#x…

多应用模式下,忽略项目的入口文件,重写Apache规则

多应用模式下&#xff0c;忽略项目的入口文件&#xff0c;重写Apache规则 首先&#xff0c;我的项目是具有两个应用&#xff0c;admin和index,同时给它们绑定了域名&#xff0c;但是每次访问时都需要加入项目的入口文件地址 index.php ,为了忽略这个入口文件&#xff0c;只能通…

Linux 进程

目录 进程与程序main()函数由谁调用&#xff1f;程序如何结束&#xff1f;何为进程&#xff1f;进程号 进程的环境变量应用程序中获取环境变量添加/删除/修改环境变量清空环境变量环境变量的作用 进程的内存布局进程的虚拟地址空间fork()创建子进程父、子进程间的文件共享系统调…

恢复已删除的git分支

1.打开对应项目文件夹目录,在目录下执行git命令 2.执行命令 git reflog --dateiso , 找到最后一次commit 的id 3. 执行git checkout -b 新建分支名称 commitId 就会基于commitId这次提交时工作区新建一个分支&#xff0c;就能达到我们找到删除分支的代码效果。 4.直接看ide…

HTTP协议详解:互联网通信背后的规则与秘密

个人主页&#xff1a;insist--个人主页​​​​​​ 本文专栏&#xff1a;网络基础——带你走进网络世界 本专栏会持续更新网络基础知识&#xff0c;希望大家多多支持&#xff0c;让我们一起探索这个神奇而广阔的网络世界。 目录 一、HTTP协议的基本概念 二、HTTP协议的主要特…

文件包含漏洞利用的几种方法

文章目录 安装环境启动环境漏洞花式利用蚁剑连接图片马读取敏感文件&#xff08;hosts&#xff09;读取该网站的php源码 代码审计 安装环境 安装phpstudy&#xff0c;下载MetInfo 5.0.4版本软件&#xff0c;复制到phpstudy目录下的www目录中。 打开phpstudy&#xff0c;访问浏…

【JavaSE】String类

两种创建String对象的区别 String s1 "hello"; String s2 new String("hello");s1是先查看常量池是否有 “hello” 数据空间&#xff0c;如果有就直接指向它&#xff0c;如果没有就创建然后指向它。s1最终指向的是常量池的空间地址。 s2是先在堆中创建空…

C++笔记之临时变量与临时对象与匿名对象

C笔记之临时变量与临时对象与匿名对象 code review! 文章目录 C笔记之临时变量与临时对象与匿名对象1.C中的临时变量指的是什么&#xff1f;2.C中的临时对象指的是什么&#xff1f;3.C中临时对象的作用是什么&#xff1f;什么时候要用到临时对象?4.给我列举具体的例子说明临…

问题记录:jenkins添加节点时Launch method没有Launch agents via SSH选项

jenkins问题记录 在jenkins主页&#xff0c;左侧点击Manage Jenkins&#xff0c;找到plugins选项&#xff0c;搜索如下插件安装&#xff1a; 安装完插件后&#xff0c;即可看到ssh选项出来了

NodeJS的简介以及下载和安装

本章节会带大家下载并安装NodeJs 以及简单的入门&#xff0c;配有超详细的图片&#xff0c;一步步带大家进行下载与安装 NodeJs简介关于前端与后端Node是什么&#xff1f;为什么要学习NodeNodeJS的优点&#xff1a; NodeJS的下载与安装NodeJS的下载&#xff1a; NodeJS的快速入…

浏览器端vscode docker搭建(附带python环境)

dockerfile from centos:7 #安装python环境 run yum -y install wget openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel zlib-devel libffi-devel gcc make run wget https://www.python.org/ftp/python/3.9.0/Python-3.9.0.tgz run tar -xvf Python-3.9.…

Elasticsearch 7.6 - API高阶操作篇

ES 7.6 - API高阶操作篇 分片和副本索引别名添加别名查询所有别名删除别名使用别名代替索引操作代替插入代替查询 场景实操 滚动索引索引模板创建索引模板查看模板删除模板 场景实操一把索引的生命周期数据迁移APIGEO(地理)API索引准备矩形查询圆形查询多边形查询 自定义分词器…