题目要求统计从 1 到 n 的所有整数中,数字 k 出现了多少次。例如 n=25,k=2 时,数字 2 在哪些数中出现:2、12、20、21、22、23、24、25,其中 22 出现了两次 2,因此总次数为 9 次。
数据范围中,1 ≤ n ≤ 1000,1 ≤ k ≤ 9,n 的值很小,可以直接采用暴力枚举的做法。
我们可以依次检查 1 到 n 中的每一个整数,统计该整数的各个十进制位中有多少个数字等于 k,然后把所有统计结果累加起来。
关键在于如何统计一个整数中数字 k 的出现次数:
这样就能得到单个数字中 k 的出现次数。
check(x, k),用来返回整数 x 中数字 k 出现的次数:
cnt = 0tmp = x % 10tmp == k 则 cnt++x = x / 10cntans = 0i 从 1 到 n:
ans += check(i, k)ans对于每个整数 i,check 函数需要循环它的位数次,对于 n 最大为 1000,每个数最多有 4 位(如 1000)。因此总操作次数约为 n × 4,最多约 4000 次,完全可以在一秒内完成,时间复杂度为 O(n log₁₀ n)。
cpp1#include <iostream> 2using namespace std; 3 4// 统计整数 x 中数字 y 出现的次数 5int check(int x, int y) { 6 int cnt = 0; 7 while (x > 0) { 8 int tmp = x % 10; // 取出个位 9 if (tmp == y) { // 如果等于目标数字 10 cnt++; // 计数器加一 11 } 12 x = x / 10; // 去掉个位 13 } 14 return cnt; 15} 16 17int main() { 18 int n, k; 19 cin >> n >> k; 20 int ans = 0; 21 for (int i = 1; i <= n; i++) { 22 ans += check(i, k); // 累加每个数中 k 的出现次数 23 } 24 cout << ans << endl; 25 return 0; 26}
check 函数:通过反复取个位并除以 10 的方式逐位检查,统计等于 k 的位数。i 从 1 到 n,依次将每个数传入 check 并将结果累加到 ans。