【GESP】C++一级真题 luogu-B4496, [GESP202603 一级] 数字替换
2026年3月,GESP一级真题,考察循环结构与数位取值,难度★☆☆☆☆。
B4496 [GESP202603 一级] 数字替换
题目要求
题目描述
Alice 不喜欢数字 $4$,但觉得数字 $8$ 寓意好,她想把数中的 $4$ 全都替换成 $8$,若数中不含 $4$ 则无需修改,你能帮帮她吗?
输入格式
输入一行,包含一个整数 $A$,表示替换前的数。
输出格式
输出一行,包含一个整数 $B$,表示替换后的数。
输入输出样例 #1
输入 #1
1
8459045
输出 #1
1
8859085
输入输出样例 #2
输入 #2
1
123
输出 #2
1
123
说明/提示
数据范围
保证 $0\le A\le 10^8$。
题目分析
这道题目要求我们将一个给定的数字 $A$ 中出现的所有数字 $4$ 替换为数字 $8$。根据 GESP 一级的考纲要求,最标准的做法是利用包含整除和取余的循环来进行数位分离。
- 数位分离:每一次循环中,我们通过
A % 10取出数字 $A$ 当前的个位数字。 - 判断与替换:判断这个取出的数字是不是 $4$。如果是 $4$,我们让它变成 $8$;如果不是,保持原样。
- 重新组合:把处理过的数字按照原来的位阶(个位、十位、百位……)拼装成一个新的数字。拼装的过程中,我们需要一个权值乘数来代表当前处理的位数(例如:个位乘 1,十位乘 10,百位乘 100)。
- 剔除旧数字末位:每次取出个位并处理合位后,通过
A / 10将原有的 $A$ 的个位砍掉,为下一次循环提取下一位数字做准备。 - 0 的特判:需要注意的是,输入数据范围是 $0 \le A \le 10^8$。如果输入的数字 $A$ 本身就是 $0$,根据数位分离循环的常规写法(
while (A > 0)),循环可能根本不会执行,导致没有输出或者输出错值,为了严谨,需要考虑输入为0的特殊情况,但在这个题目里,$0$ 不包含 $4$,原样输出即正确。
下面讲解利用一级考纲知识和超纲知识两种思路。
示例代码
非超纲解法(推荐)
对于 GESP 一级考试,熟练掌握整除(/)和取模(%)操作是非常关键的。这套“分离-判断-拼凑”的流程是一级考试中最经典的循环应用之一。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
int main() {
int A;
std::cin >> A;
// 如果输入的本来就是0,里面没有4,直接输出0
if (A == 0) {
std::cout << 0 << std::endl;
return 0;
}
// 准备一个变量,用来装配替换后的新数字,初始为 0
int B = 0;
// 准备一个变量,表示当前的位数(个位是1,十位是10,百位是100)
int weight = 1;
// 当 A 还没有被我们剥削干净时,一直循环
while (A > 0) {
// 第一步:把 A 当下的个位取出来
int digit = A % 10;
// 第二步:判断是不是我们要替换的 4
if (digit == 4) {
// 如果是 4,变成了 8(注意这里只改变取出来的值,并未改变原图)
digit = 8;
}
// 第三步:把处理后的数字,根据它原本应该在的位数,拼装给新数字 B
B = B + digit * weight;
// 第四步:去掉刚才已经处理完的 A 的个位
A = A / 10;
// 第五步:位数权值变大十倍,为下一轮循环处理更高位做准备
weight = weight * 10;
}
// 输出处理好的新数字 B
std::cout << B << std::endl;
return 0;
}
超纲解法(拓展思维)
如果学习过字符串(string),这道题的逻辑会变得异常简单。“替换”本来就是一个在文字或者字符序列里常见的功能。我们可以直接把输入的这个大数字当作一个“字符串”(一段文字)来接收,然后扫过每一个字符,看到字符 '4' 就换成字符 '8',最后输出这段文字即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
// 引入 string 头文件,以便使用字符串(三级考纲知识点)
#include <string>
int main() {
// 声明一个字符串变量用来接收输入
std::string str;
std::cin >> str;
// 利用 for 循环,遍历字符串里的每一个字符。
// str.length() 函数用来获取字符串一共有多少个字
for (int i = 0; i < str.length(); ++i) {
// 如果发现第 i 个位置存放的是字符 '4' (注意单引号)
if (str[i] == '4') {
// 直接覆盖为字符 '8'
str[i] = '8';
}
}
// 重新把字符串输出即可
std::cout << str << std::endl;
return 0;
}
所有代码已上传至Github:https://github.com/lihongzheshuai/yummy-code
GESP 学习专题站:GESP WIKI
“luogu-”系列题目可在洛谷题库进行在线评测。
“bcqm-”系列题目可在编程启蒙题库进行在线评测。
欢迎加入:Java、C++、Python技术交流QQ群(982860385),大佬免费带队,有问必答
欢迎加入:C++ GESP/CSP认证学习QQ频道,考试资源总结汇总
欢迎加入:C++ GESP/CSP学习交流QQ群(688906745),考试认证学员交流,互帮互助
