week3-[循环嵌套]好数
week3-[循环嵌套]好数
题目描述
如果一个正整数 xxx 只有最左边一位不是 000,其余都是 000,那么称其为好数。例如 400040004000 和 222 都是好数,但是 120120120 不是。
给定正整数 nnn,在 111 到 nnn 间有多少个数是好数?又有多少个数能表示为两个好数的和?
输入格式
输入共 111 行 111 个正整数 nnn。
输出格式
输出共 222 行。
第 111 行 111 个整数表示有多少个数是好数。
第 222 行 111 个整数表示有多少个数能表示为两个好数之和。
样例 #1
样例输入 #1
15
样例输出 #1
10
14
提示
样例解释 111
1,2,3,4,5,6,7,8,9,101,2,3,4,5,6,7,8,9,101,2,3,4,5,6,7,8,9,10 都是好数。
数据范围
对于所有数据,1≤n≤100001\leq n\leq 100001≤n≤10000。
这题分两部分:统计好数 和 统计能表示为两个好数之和的数。
🔎 分析
1️⃣ 什么是好数
- 定义:只有最左边一位不是
0
,其余都是0
。 - 也就是形式为
d * 10^k
,其中d=1~9
,k ≥ 0
。 - 例子:
2
→ 好数10
→ 好数120
→ 不是好数
方法:
- 对 1~n 遍历:
- 转字符串检查是否首位非零,其余都是零
- 或者数学方法:判断
x
是否能被其首位数字后的 10 的幂整除
2️⃣ 统计能表示为两个好数之和的数
- 先生成所有好数
good[]
≤ n - 枚举所有两两组合
good[i] + good[j] ≤ n
→ 计数 - 注意:不同组合得到相同的和只算一次 → 用布尔数组
ok[1..n]
标记
📝 C++ 实现
#include <bits/stdc++.h>
using namespace std;// 判断一个数是否为好数
bool isGood(int x) {while (x % 10 == 0 && x > 0) x /= 10; // 去掉末尾0return x >= 1 && x <= 9; // 去掉末尾0后是否在1~9
}int main() {int n;cin >> n;vector<int> good;for (int i = 1; i <= n; i++) {if (isGood(i)) good.push_back(i);}cout << good.size() << endl;vector<bool> can(n+1, false);for (int i = 0; i < good.size(); i++) {for (int j = i; j < good.size(); j++) {int sum = good[i] + good[j];if (sum <= n) can[sum] = true;}}int cnt = 0;for (int i = 1; i <= n; i++) if (can[i]) cnt++;cout << cnt << endl;return 0;
}c++