当前位置: 首页 > news >正文

[GESP202306 四级] 2023年6月GESP C++四级上机题超详细题解,附带讲解视频!

本文为2023年6月GESP C++四级的上机题目的详细题解!觉得写的不错或者有帮助可以点个赞啦!

(第一次讲解视频,有问题可以指出,不足之处也可以指出)

题目一讲解视频:

2023年6月GESP C++四级上机题一

题目二讲解视频:

【有点复杂,制作中!】

题目一: 幸运数

B3850 [GESP202306 四级] 幸运数 - 洛谷

题目大意:

题目首先定义了,一个数字的个位数为第一位,十位数为第二位...以此内推。

然后呢,对于一个数字num的奇数位置,提取出来,然后进行如下操作:

定义这个数字为x,易得0 <= x <= 9。现在将x * 7,然后现在不断的进行以下的操作,直到x小于等于9:

求出此时x的数位和sum,然后把x赋值成sum。

经过上述操作后,把x放回原来的位置。

如果num的数位和是8的倍数,那么num是幸运数,输出T,否则输出F。

解题思路:

题目主要考察的是模拟,代码实现能力

根据题目意思,我们主要的操作对象是num的奇数位置,我们可以把num转换成字符串,可以输入的时候直接用字符串变量接收。

注意个位数是字符串的最后一位,我们从字符串的最后一位开始遍历,然后每次让i -= 2即可保证获取的是“奇数位置”。

然后根据题目意思进行模拟,在while (x > 9)的循环里面不断的求出当前x的数位和,赋值给x,最后得出的x,直接把原来的位置的字符变成新的x即可,注意数字和字符之间的转换。

最后不要忘记求出数位和,然后再判断是否是8的倍数。

注意题目输入的是N个数字,我们对每一个数字单独判断。

没什么用的小优化:每个“奇数位置”的操作都是单独进行的,那么肯定有一个对应值,我们可以先把每个数字操作的结果求出来放在数组里面,然后直接使用即可。

代码(C++):

#include <bits/stdc++.h>
//https://blog.csdn.net/2401_83669813 csdn: @立志成为算法讲师void solve() {//2.std::string s;std::cin >> s;int n = s.size();//3.for (int i = n - 1; i >= 0; i -= 2) {int num = s[i] - '0';num *= 7;//4.5.while (num > 9) {int t = num;int sum = 0;while (t > 0) {sum += t % 10;t /= 10;}num = sum;}//6.s[i] = num + '0';}int sum = 0;for (char c : s) {sum += c - '0';}if (sum % 8 == 0) {std::cout << "T\n";} else {std::cout << "F\n";}
}int main() {/*1.捆绑测试2.把数字当成字符串输入3.从最后一位开始遍历4.变换操作5.当数字大于9的时候,不断的求数位和,然后赋值给新的数字6.把变换后的数字赋值回去*/int N;std::cin >> N;while (N--) {solve();}
}

题目二:图像压缩

B3851 [GESP202306 四级] 图像压缩 - 洛谷

题目大意:

给你n个长度为偶数,并且都相等的字符串s,这n个字符串组成一幅256级灰阶的灰度图像。

对于其中的一个字符串,每两个字符组成一个字符串,表示一个16进制的数字,大小为0到255,也就是16进制的0到FF,这个大小表示这个像素点的灰阶。题目保证n个字符串包含的灰阶至少有16种。

现在我们要把这个256级灰阶的灰度图像压缩成16级的灰度图像。

压缩方式为:

统计出这个图像每一个灰阶的数量,然后取数量最大的16种,如果存在灰阶数量相同的灰阶,那么灰阶值小的在前面。

先把这16种灰阶按照从大到小的顺序输出出来。

现在把这数量最大的16种灰阶编号为0到F,也就是十进制的0到15。

对于其他的灰阶y,我们计算出灰度与16个灰阶最近的值(灰阶大小,不是个数),也就是绝对值大小,把y编号成相差的绝对值最小的那个,如果有绝对值相同的点,那么我们就编号成编号小的那个。

然后把压缩后的图像输出出来。

解题思路:

本题主要考察,进制的转换,位运算,自定义排序,模拟,代码实现能力。


我们首先把握题目的关键要求,把每两个字符组成的字符串作为一个16进制数字,计算出出现次数最多的16个16进制数字,并且后面的排序和作差都要关注这16个16进制数字的大小。

那么我们可以这么写,先把16进制转换成10进制,然后我们用一个长度为256的数组cnt来记录每一个16进制数字出现的次数。也就是cnt[i]为大小为i的数字的出现次数。


统计了出现次数后,我们现在进行自定义排序,求出里面最大的那16个数字。

由于题目要求:然后取数量最大的16种,如果存在灰阶数量相同的灰阶,那么灰阶值小的在前面。

那我们可以这么简单的写,我们直接用一个数组id,来存0到255这些数字,然后排序这个数组,数组里面两个数字的cnt[a] != cnt[b]的时候,cnt大的在前面,否则就是数字小的在前面。

这样操作之后数组id里面的前16个数字就是我们想要的16个数字了。

可以先输出出来,记得按照题目转换回原来的16进制。


最后我们要实现的是,输出压缩后的图像,对于每一个16进制的数字,先转换成10进制,然后根据题目要求求出差的绝对值最小的那个,再根据题目要求编号成0 - F即可。

具体实现详见代码。

代码(C++):

#include <bits/stdc++.h>//单个字符转换成数字
int toNum(char c) {if (c <= '9') {return c - '0';}return c - 'A' + 10;
}//数字转换成字符
char toChar(int num) {if (num <= 9) {return num + '0';}return num + 'A' - 10;
}//转换成10进制数字
int to10(std::string s) {return ((toNum(s[0]) << 4) | toNum(s[1]));
}//转换成16进制的数字
std::string to16(int num) {std::string res(2, '0');res[0] = toChar(num >> 4);res[1] = toChar(num & 15);return res;
}int main() {int n;std::cin >> n;std::vector<std::string> a(n);for (int i = 0; i < n; i++) {std::cin >> a[i];}int m = a[0].size();std::vector<int> cnt(256);for (auto& s : a) {for (int i = 0; i < m; i += 2) {std::string cur = s.substr(i, 2);int num = to10(cur);cnt[num]++;}}std::vector<int> id(256);for (int i = 0; i < 256; i++) {id[i] = i;}std::sort(id.begin(), id.end(), [&](int u, int v) {if (cnt[u] != cnt[v]) {return cnt[u] > cnt[v];}return u < v;});for (int i = 0; i < 16; i++) {std::cout << to16(id[i]);}std::cout << "\n";for (auto& s : a) {for (int i = 0; i < m; i += 2) {std::string cur = s.substr(i, 2);int mnDiff = 256, mnIdx = 0;for (int i = 0; i < 16; i++) {int diff = abs(to10(cur) - id[i]);if (diff < mnDiff || (diff == mnDiff && i < mnIdx)) {mnIdx = i;mnDiff = diff;}}std::cout << toChar(mnIdx);}std::cout << "\n";}
}

http://www.dtcms.com/a/314152.html

相关文章:

  • 事件(二)实战案例
  • Do-Calculus:因果推断的演算基础与跨领域应用
  • 17.6 超拟人大模型CharacterGLM技术解析:92.7%角色一致性+虚拟偶像互动提升300%,如何吊打GPT-4?
  • Maya 2024安装指南及安装包下载
  • UILabel设置字重
  • Coze Loop:开源智能体自动化流程编排平台原理与实践
  • Ethereum: 深度解析Web3世界的合规之门, ERC-1400证券型代币标准
  • Oracle ASH的手册
  • Linux定制篇-Tomcat的安装和配置
  • Druid学习笔记 03、Druid的AstNode类详解与其他产品测试体验
  • 【精品项目】进阶版贪吃蛇:现代Web技术打造的经典游戏重生
  • 从零认识OpenFlow
  • TCP为什么采用三次握手而不是二次握手
  • 使用 Marian 进行机器翻译详解及对应案例
  • 在安卓中使用 FFmpegKit 剪切视频并添加文字水印
  • Android进程基础:Zygote
  • (JAVA)自建应用调用企业微信API接口,设置企业可信IP
  • 开疆智能ModbusTCP转Profient网关连接ER机器人配置案例
  • DPDK中的TCP头部处理
  • 第五篇: 深入解析基于 SQLAlchemy 的聊天记录持久化模块:`message_model` 与数据库操作封装
  • 高速信号设计之 PCIe6.0 篇
  • Windows中Idea或者其他开发工具如何使用Google Sans Code - 码农开源等宽字体
  • 数据结构:如何判断一个链表中是否存在环(Check for LOOP in Linked List)
  • JSqlParser学习笔记 快速使用JSqlParser
  • 从exec到Shell:深度解析Linux进程等待,程序替换与自主Shell实现
  • 电脑一键重装系统win7/win10/win11无需U盘(无任何捆绑软件图文教程)
  • OBS 基础 21 充满某个源的策略
  • Android GPU测试
  • 电子电气架构 ---智能电动汽车嵌入式软件开发过程中的block点
  • 【Linux指南】软件安装全解析:从源码到包管理器的进阶之路