美文网首页
页码统计

页码统计

作者: RobotBerry | 来源:发表于2017-04-27 10:20 被阅读0次

    问题描述

    牛牛新买了一本算法书,算法书一共有n页,页码从1到n。牛牛于是想了一个算法题目:在这本算法书页码中0~9每个数字分别出现了多少次?

    输入描述

    输入包括一个整数n(1 ≤ n ≤ 1,000,000,000)

    输出描述

    输出包括一行10个整数,即0~9这些数字在页码中出现的次数,以空格分隔。行末无空格。

    输入例子

    999

    输出例子

    189 300 300 300 300 300 300 300 300 300

    分析

    参考《编程之美》和《剑指offer》的算法。

    假设一个数N被表示为XDY,X和Y都是一串数字,长度为[0-∞];D是一个数字,大小为[0-9]。要注意的是,当X的长度为0,即D是最高位数字时,D不能为0。

    现在要分析[1-N]这N个数在D位上出现数字d的次数C。我们可以举一个具体的例子,当X=12,Y=56时,N=12D56,设d=1。根据D的大小情况,分下面三种情况讨论:

    • D < 1
      即D=0,此时在D位上出现1的情况有:100-199,1100-1199,2100-2199,...,11100-11199,总共1200个;

    • D = 1
      此时在D位上出现1的情况有:100-199,1100-1199,2100-2199,...,11100-11199,12100-12156,总共1200+156+1个;

    • d > 1
      此时在D位上出现1的情况有:100-199,1100-1199,2100-2199,...,11100-11199,12100-12199,总共1300个;

    设Y的位数为pY。至此我们可以得出结论:当D<1时,C=X10^pY;当D=1时,C=X10pY+Y+1;当D>1时,C=(X+1)*10pY。

    同理,这个结论对d∈[1,9]都适用。当d=0时,pY项改成pY-1即可。因为0不能作为最高项。例如上面D的三种情况,如果d=1,每种情况都有100-199;但是如果d=0,则不能出现000-099,这样就正好少了X*10项。

    note

    1. 多列几个具体的例子,找找规律;
    2. 要善于分类讨论。

    代码

    字符串处理后转数字

    #include <cstdio>
    #include <vector>
    #include <string>
    #include <algorithm>
    
    using namespace std;
    
    long long countDigit(const string &str, int i, int j)
    {
        int p = str.size() - i;
        int d = str[p - 1] - '0';
    
        string upperStr = str.substr(0, p - 1);
        string lowerStr = str.substr(p, i);
    
        long long upperNum = upperStr.empty() ? 0 : stoll(upperStr);
        long long lowerNum = lowerStr.empty() ? 0 : stoll(lowerStr);
    
        if (j == 0) upperNum--;
    
        if (d < j)
            return upperNum * pow(10, i);
        if (d == j)
            return upperNum * pow(10, i) + lowerNum + 1;
        return (upperNum + 1) * pow(10, i);
    }
    
    int main()
    {
        char str[11];
        scanf("%s", str);
        string num(str);
    
        vector<long long> cnt(10, 0);
        for (int i = 0; i < num.length(); i++)
            for (int j = 0; j < 10; j++)
                cnt[j] += countDigit(str, i, j);
    
        printf("%d", cnt[0]);
        for (int i = 1; i < 10; i++)
            printf(" %d", cnt[i]);
    
        return 0;
    }
    

    数字计算

    #include<iostream>
    
    using namespace std;
    
    int count(int n, int x) 
    {
        int cnt = 0;
        for (int i = 1, j; j = n / i; i *= 10) 
        {
            int high = j / 10;
            int low = n - j * i;
            int digit = j % 10;
    
            if (x == 0) high--;
    
            cnt += high * i;
            if (digit > x)
                cnt += i;
            else if (digit == x)
                cnt += low + 1;
        }
    
        return cnt;
    }
    
    int main() 
    {
        int n;
        cin >> n;
    
        cout << count(n, 0);
        for (int i = 1; i <= 9; i++)
            cout << " " << count(n, i);
    
        return 0;
    }
    

    相关文章

      网友评论

          本文标题:页码统计

          本文链接:https://www.haomeiwen.com/subject/hedgzttx.html