【GESP 一级】洛谷 B3864 小明的幸运数 题解
一、题目概述
本题是GESP 2023 年 9 月一级认证真题,对应洛谷题号 B3864,是入门阶段的经典条件筛选与累加求和题,核心是根据双重条件筛选数字并计算总和。
题目可以简化为:输入三个整数k、L、R,求区间[L, R]内,所有满足以下条件之一的数字之和:
- 数字的个位数是 k;
- 数字是k 的倍数。
注意:如果一个数同时满足两个条件(比如7,既是 7 的倍数,个位也是 7),只计算一次,不重复累加。
二、核心考察点
这道题覆盖了 GESP 一级的多个高频考点,同时锻炼了逻辑判断和去重思维:
| 考点 | 考察内容 | 难度 |
|---|---|---|
| 循环结构 | 使用for循环遍历区间[L, R]内的所有数字 | ⭐⭐ |
| 条件判断 | 双重条件筛选(个位数判断 + 倍数判断) | ⭐⭐⭐ |
| 取模运算 | %10获取个位数、%k判断倍数 | ⭐⭐ |
| 变量累加 | 使用变量记录符合条件数字的总和 | ⭐⭐ |
| 逻辑去重 | 避免同时满足两个条件的数字被重复计算 | ⭐⭐⭐ |
三、解题思路分析
1. 核心逻辑拆解
要解决这道题,我们需要:
- 遍历区间
[L, R]内的每一个数字i; - 判断
i是否满足 “个位数为 k”或“是 k 的倍数”; - 如果满足条件,就把
i累加到总和变量中; - 遍历结束后,输出总和。
关键细节:用if (条件1 || 条件2)可以天然实现去重,因为||逻辑或只会让条件成立的数字被加一次,不会重复计算。
2. 两个关键条件的实现
- 个位数是 k:数字的个位数可以用
i % 10获取,判断条件为i % 10 == k; - 是 k 的倍数:判断条件为
i % k == 0。
3. 整体解题流程
- 读取输入的三个整数
k、L、R; - 初始化总和变量
sum = 0; - 用
for循环从L遍历到R:- 对每个数字
i,判断是否满足i % 10 == k || i % k == 0; - 如果满足,
sum += i;
- 对每个数字
- 循环结束后,输出
sum。
四、易错点提醒(考试避坑)
区间边界错误循环必须从
L开始,到R结束(for (int i = L; i <= R; i++)),题目要求包括L和R。重复计算问题不能用两个独立的
if语句分别判断条件(比如先判断个位数,再判断倍数,都累加),否则会导致同时满足两个条件的数字被加两次,结果偏大。个位数判断错误个位数是用
i % 10,不是i / 10,后者得到的是十位数及以上的部分。倍数判断的顺序倍数判断是
i % k == 0,不是k % i == 0,后者逻辑完全颠倒。边界值测试
- 数字同时满足两个条件:如样例 1 中的
7,只计算一次; - 区间内没有符合条件的数字:如
k=7, L=8, R=13,结果为 0; - 区间只有一个数字:如
L=R=7,结果为 7。
- 数字同时满足两个条件:如样例 1 中的
五、完整 C++ 代码
#include <iostream> using namespace std; int main() { int k, L, R; cin >> k; cin >> L; cin >> R; int sum = 0; // 初始化总和为0 // 遍历区间[L, R]内的所有数字 for (int i = L; i <= R; ++i) { // 判断是否满足条件之一:个位是k 或 是k的倍数 if (i % 10 == k || i % k == 0) { sum += i; // 符合条件,累加到总和 } } cout << sum << endl; return 0; }六、扩展练习(举一反三)
学会这道题的核心逻辑后,可以试试以下扩展练习,巩固类似的条件筛选与累加能力:
练习 1:修改条件 —— 双条件同时满足
题目变形:求区间[L, R]内,同时满足“个位数是 k” 和 “是 k 的倍数” 的数字之和。
- 提示:把
||改成&&即可。
练习 2:扩展位数 —— 十位数也是 k
题目变形:求区间[L, R]内,个位数是 k或十位数是 k或是 k 的倍数的数字之和。
- 提示:十位数可以用
i / 10 % 10获取,新增条件(i / 10) % 10 == k。
练习 3:反向筛选 —— 排除特定数字
题目变形:求区间[L, R]内,不满足“个位数是 k” 也不是“k 的倍数” 的数字之和。
- 提示:把条件改成
!(i % 10 == k || i % k == 0),或者用&&连接两个否定条件。
练习 4:多条件计数 —— 统计幸运数个数
题目变形:不计算和,改为统计区间[L, R]内,符合条件的 “幸运数” 有多少个。
- 提示:把累加
sum += i改成计数变量cnt++,最后输出cnt。
练习 5:自定义规则 ——“k 的幸运数字” 升级
题目变形:自定义 “幸运数字” 规则,比如:
- 规则 A:数字包含数字 k(如 k=7,数字 17、71、70 都算);
- 规则 B:数字是 k 的倍数,或者各位数字之和是 k;求区间
[L, R]内符合规则的数字之和。
七、总结
这道题的核心是循环遍历 + 多条件筛选 + 累加求和,是 GESP 一级中非常经典的综合应用题。
通过这道题,你不仅掌握了取模运算、循环遍历和条件判断,还理解了逻辑或(||)的去重特性,这对后续学习更复杂的筛选问题非常有帮助。
