文章

【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 一级的考纲要求,最标准的做法是利用包含整除和取余的循环来进行数位分离

  1. 数位分离:每一次循环中,我们通过 A % 10 取出数字 $A$ 当前的个位数字。
  2. 判断与替换:判断这个取出的数字是不是 $4$。如果是 $4$,我们让它变成 $8$;如果不是,保持原样。
  3. 重新组合:把处理过的数字按照原来的位阶(个位、十位、百位……)拼装成一个新的数字。拼装的过程中,我们需要一个权值乘数来代表当前处理的位数(例如:个位乘 1,十位乘 10,百位乘 100)。
  4. 剔除旧数字末位:每次取出个位并处理合位后,通过 A / 10 将原有的 $A$ 的个位砍掉,为下一次循环提取下一位数字做准备。
  5. 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),考试认证学员交流,互帮互助

GESP/CSP 认证学习微信公众号
GESP/CSP 认证学习微信公众号
本文由作者按照 CC BY-NC-SA 4.0 进行授权