美文网首页
页码统计

页码统计

作者: 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;
}

相关文章

  • 页码统计

    问题描述 牛牛新买了一本算法书,算法书一共有n页,页码从1到n。牛牛于是想了一个算法题目:在这本算法书页码中0~9...

  • 页码统计

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

  • [编程题] 页码统计

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

  • Office小技巧-Word插入页码大全

    当我们在写论文或者报告的时候,经常需要我们给文档设置页码,用于页码统计,也方便后期的查阅和阅读,但是经常遇到特殊的...

  • 页码

    选书的时候,会尽量选内容饱满的书籍,方正字体爬满整页,没有空白,值得我慢慢去读。白纸黑字,只留一隅给页码,几个数...

  • 页码

  • 《发现灰兔侠》目录

    记录Sally发现灰兔侠的故事 页码:1-4 页码:5-8 页码:9-12 页码:13-18 页码:19-22

  • ThinkPHP 5.0 页码展示修改

    页码显示样式修改 修改手机端展示样式,增加页码显示,并且修改页码展示数量 /** * 手机端页码按钮 * @ret...

  • 作业—页码

  • word页码

    word文档编排时候,需要插入页码。有的要求可能是从第n页开始才是页码编号为1,这时候如果直接插入页码,那么本应该...

网友评论

      本文标题:页码统计

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