页码统计

2017-04-27  本文已影响0人  RobotBerry

问题描述

牛牛新买了一本算法书,算法书一共有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的大小情况,分下面三种情况讨论:

设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;
}
上一篇下一篇

猜你喜欢

热点阅读