top1编程
← 返回题目
题解

数字出现的次数

1 条题解

  • 0
    @ 2026-8-4 1:13:28

    解题思路

    两个大整数的位数都接近 1000 位,早就超过 long long 能存的范围了,所以要学一个专门的技能:高精度加法。

    思路是:像我们平时在纸上列竖式算加法一样,从个位开始,一位一位加,满 10 就往前进 1。

    具体做法:

    1. 把两个大数当字符串读进来。
    2. 倒着放进数组:个位放在下标 0,十位放在下标 1……这样从下标 0 开始就是"从低位往高位"算,非常方便。
    3. 逐位相加:s[i] = a[i] + b[i] + 进位。
    4. 如果某一位 >= 10,就减 10,并且下一位加 1(进位)。
    5. 加完后,统计数组里每一位等于 m 的个数,就是答案。

    参考代码

    // 用途:两个大整数相加,统计数字m(0~9)在和中出现的次数
    // 大整数位数<1000,用字符数组读入,逐位相加存到数组
    #include <iostream>
    using namespace std;
    int main() {
        char a[1005], b[1005];
        int ca[1005] = {0}, cb[1005] = {0}, s[1005] = {0}; // 倒序存储的数组
        int m;
        cin >> a >> b >> m;
        int la = 0, lb = 0;
        while (a[la]) la++;   // a的位数
        while (b[lb]) lb++;   // b的位数
        for (int i = 0; i < la; i++) ca[i] = a[la - 1 - i] - '0'; // 倒序存入
        for (int i = 0; i < lb; i++) cb[i] = b[lb - 1 - i] - '0';
        int len = (la > lb) ? la : lb;   // 和的位数至少是较长的那个
        for (int i = 0; i < len; i++) {  // 逐位相加
            s[i] += ca[i] + cb[i];
            if (s[i] >= 10) {            // 满10进位
                s[i] -= 10;
                s[i + 1]++;
            }
        }
        if (s[len]) len++;               // 最高位可能再进一位
        int cnt = 0;
        for (int i = 0; i < len; i++)
            if (s[i] == m) cnt++;        // 统计数字m出现的次数
        cout << cnt;
        return 0;
    }
    

    复杂度分析

    加法需要处理两个数每一位,设位数最多为 n(本题不超过 1000),时间复杂度是 O(n),空间复杂度是 O(n)。对于 1000 位的数来说完全没问题。

    • 1