


🟦 题目名称:计数
🌈 一、先看题目:
1、题目说:
小杨有一个"幸运数字" k(保证是 0~9 之间的数字)。
现在给你一个整数 n。
2、问:
👉 从 1 到 n 所有数字里
👉 数字 k 一共出现了多少次?
🧸 二、举例说明:
1、比如:
cpp
n = 25
k = 2
2、我们要看:
从 1 到 25 里面
数字"2"出现了几次?
3、我们来数一数 👀
cpp
1
2 ← 1次
3
...
10
11
12 ← 1次
...
20 ← 1次
21 ← 1次
22 ← 2次
23 ← 1次
24 ← 1次
25 ← 1次
4、统计一下:
2 (1次)
12(1次)
20(1次)
21(1次)
22(2次)
23(1次)
24(1次)
25(1次)
5、总共:
1 + 1 + 1 +1+ 2+1+1+1 = 9次
6、所以答案是:
cpp
9
🧠 三、算法步骤:
1、我们要做两件事:
(1)第一步
遍历:
cpp
for (i = 1 到 n)
(2)第二步
检查每一个数里面:
数字 k 出现了几次?
🧮 四、怎么检查一个数的"每一位"?
1、比如:
1234
2、怎么一位一位拆?
方法是:
cpp
% 10 → 取最后一位
/ 10 → 去掉最后一位
3、🎯 举例:123
(1)第一次:
cpp
123 % 10 = 3
123 / 10 = 12
(2)第二次:
cpp
12 % 10 = 2
12 / 10 = 1
(3)第三次:
cpp
1 % 10 = 1
1 / 10 = 0
(4)结束!
💻 五、参考程序:
cpp
#include <iostream>
using namespace std;
int check(int x, int y) {
int cnt = 0;
while (x > 0) {
int tmp = x % 10;
if (tmp == y) {
cnt++;
}
x = x / 10;
}
return cnt;
}
int main() {
int n, k;
cin >> n >> k;
int ans = 0;
for (int i = 1; i <= n; i++) {
ans += check(i, k);
}
cout << ans << endl;
return 0;
}
💻 六、代码讲解:
cpp
int check(int x, int y) {
int cnt = 0;
while (x > 0) {
int tmp = x % 10;
if (tmp == y) {
cnt++;
}
x = x / 10;
}
return cnt;
}
(1)🧠 这段代码意思是:
函数 check:
返回:
👉 数字 x 里面
👉 数字 y 出现了多少次?
(2)主程序讲解
cpp
int main() {
int n, k;
cin >> n >> k;
int ans = 0;
for (int i = 1; i <= n; i++) {
ans += check(i, k);
}
cout << ans << endl;
}
意思是:
从 1 到 n
把每个数里 k 出现的次数加起来。
🏆 七、超简写法(不用函数)
cpp
#include<iostream>
using namespace std;
int main(){
int n, k;
cin >> n >> k;
int ans = 0;
for(int i=1;i<=n;i++){
int x = i;
while(x){
if(x%10 == k)
ans++;
x /= 10;
}
}
cout << ans;
}
🌈 八、总结
| 步骤 | 做什么 |
|---|---|
| 1 | 遍历 1~n |
| 2 | 拆分每个数 |
| 3 | 比较每一位 |
| 4 | 有K就累加 |
| 5 | 输出最后结果 |
🌟 九、本题考点
这题是典型的:
✅ for 循环
✅ 数字拆位
✅ % 和 / 的使用
✅ 累加统计
数字拆分是二级考试必考!学生需要完全掌握!
附:🎯 拆数算法(模版大全)
🌈 一、什么叫"拆数"?
1、比如数字:
cpp
12345
2、我们要把它拆成:
cpp
5
4
3
2
1
3、怎么拆?
秘诀只有两个操作:
cpp
% 10 取最后一位
/ 10 去掉最后一位
🧠 二、万能拆数模板
cpp
while(n > 0){
int digit = n % 10; // 取最后一位
// 在这里处理 digit
n /= 10; // 去掉最后一位
}
🌟 这是必背模板!
🎯 三、常见题型 + 模板讲解
1、各位数字之和
(1)题目:
输入 123,输出 6
(2)模板代码
cpp
int sum = 0;
while(n > 0){
sum += n % 10;
n /= 10;
}
cout << sum;
2、 统计某个数字出现次数
(1)比如:
cpp
n = 12232 k = 2
统计 k 出现几次
(2)模板代码
cpp
int count = 0;
while(n > 0){
if(n % 10 == k)
count++;
n /= 10;
}
3、判断是否包含某个数字
(1)例如:
是否包含 7
(2)模板代码
cpp
bool found = false;
while(n > 0){
if(n % 10 == 7){
found = true;
break;
}
n /= 10;
}
4、反转数字(经典)
(1)例如:
输入:
123
输出:
321
(2)模板代码
cpp
int rev = 0;
while(n > 0){
rev = rev * 10 + n % 10;
n /= 10;
}
5、 判断回文数
(1)例如:
121 是回文
(2)模板代码
cpp
int original = n;
int rev = 0;
while(n > 0){
rev = rev * 10 + n % 10;
n /= 10;
}
if(original == rev)
cout << "Yes";
else
cout << "No";
🌟 四、拆数加强版(处理 0 的情况)
1、有时题目会给:
cpp
n 可能等于 0
2、模板代码
cpp
if(n == 0){
// 单独处理
}
while(n > 0){
...
}
🌟 五、支持负数版本
cpp
n = abs(n);
while(n > 0){
...
}
🌟 六、拆数算法的核心思想
cpp
每次取最低位
处理
删除最低位
重复
这是一种:
👉 循环结构
👉 数学运算
👉 模拟过程
🌟 七、考试常见变形
GESP二级常考:
统计幸运数字
统计区间数字
各位求和(乘积)
数字转置
计数问题
几乎都是拆数问题。