• 【1-1】统计数字问题


    ´问题描述:
    一本书的页码从自然数 1 开始顺序编码直到自然数 n。书的页码按照通常的习惯编排,
    每个页码都不含多余的前导数字 0。例如,第 6 页用数字 6 表示,而不是 06 或 006 等。数
    字计数问题要求对给定书的总页码 n,计算出书的全部页码中分别用到多少次数字 0,1,
    2,…,9。
    ´编程任务:
    给定表示书的总页码的 10 进制整数 n (1≤n≤109
    ) 。编程计算书的全部页码中分别用
    到多少次数字 0,1,2,…,9。
    ´数据输入:
    输入数据由文件名为 input.txt 的文本文件提供。
    每个文件只有 1 行,给出表示书的总页码的整数 n。
    ´结果输出:
    程序运行结束时,将计算结果输出到文件 output.txt 中。输出文件共有 10 行,在第 k 行
    输出页码中用到数字 k-1 的次数,k=1,2,…,10。
    输入文件示例 输出文件示例
    input.txt output.txt
    11 1
    4
    1
    1
    1
    1
    1
    1
    1
    1
    【题解】

    000..0~999..9 (n个9)
    则0~9中每个数字出现的次数都是n*10^(n-1),即每个数字出现次数相同。
    但是因为不含前导0.
    所以要把多算的0给去掉。
    具体的,设n这个数字的长度为L,则需要减去1111....1(L个1)个多余的0.
    然后做个数位DP就好。
    详见:https://www.cnblogs.com/AWCXV/p/7632451.html

    【代码】

    #include <cstdio>
    #include <iostream>
    #include <string>
    using namespace std;
    
    string s;
    int _pow = 1;
    int cnt[10];
    
    int get_num(int l,int r){
        int temp = 0;
        for (int i = l;i <= r;i++){
            temp = temp*10+s[i]-'0';
        }
        temp++;
        return temp;
    }
    
    int main(){
        cin >> s;
        int len = s.size();
        for (int i = 1;i <= len-1;i++) _pow*=10;
        for (int i = 0;i < len;i++){
            int si = s[i]-'0';
            for (int j = 0;j <= 9;j++) cnt[j]+=si*(len-i-1)*_pow/10;
            for (int j = 0;j <=si-1;j++){
                cnt[j]+=_pow;
            }
            cnt[si]+=get_num(i+1,len-1);
            _pow=_pow/10;
        }
        int more0 = 0;
        for (int i= 1;i <= len;i++){
            more0 = more0*10+1;
        }
        cnt[0]-=more0;
        for (int i = 0;i <= 9;i++){
            cout<<cnt[i]<<endl;
        }
        return 0;
    }
    
    
  • 相关阅读:
    设计模式-享元模式
    设计模式-外观模式
    设计模式-桥接模式
    设计模式-适配器模式
    设计模式-代理模式
    java设计模式中用到的UML图
    VS code 初次安装配置
    CMD部分操作、BAT、以及VS SQL部分快捷键
    网络部分
    CMD 中certutil 操作命令
  • 原文地址:https://www.cnblogs.com/AWCXV/p/11615546.html
Copyright © 2020-2023  润新知