• 【算法课】数字统计问题


    题目描述

    给定一本书,其中包含n页,计算出书的全部页码中用到了多少个数字0…9?页码从1开始
     

    输入

    一个整数n,代表页码总数。(1<=n<=1e9)
     

    输出

    十行,每行一个整数,分别表示0~9每个数字出现的次数
     

      1 /*
      2     数字统计问题
      3 */
      4  
      5 #include<cstdio>
      6 #include<cstring>
      7 #include<iostream>
      8 #include<algorithm>
      9 using namespace std;
     10 typedef long long ll;
     11  
     12 const int N = 20;
     13  
     14 ll f[20][10][10] ;
     15 ll Ans[10],Base[10],Sum[11][11];
     16 int Limit[N] , len , number;
     17 char Str[N] , T[N] ;
     18  
     19 void Input(){
     20     scanf("%s",Str+1 );
     21     strcpy( T+1 , Str+1 );
     22     len = strlen( Str+1 );
     23     sscanf( T+1 , "%d" , &number );
     24     reverse( Str + 1 , Str + 1 + len ) ;
     25 }
     26  
     27 void Init(){
     28  
     29     Base[1] = 1 ;
     30     /*转化字符串,最高位情况另外讨论。*/
     31     for( int i = 1 ; i <= len ; i ++ ){
     32         Limit[i] = Str[i] - '0' ;
     33         if( i >= 2 )
     34             Base[i] = Base[i-1] * 10 ;
     35     }
     36  
     37     /*  处理个位数时的方案数,预处理,为转移做准备   */
     38     for( int Num = 0 ; Num <= 9 ;Num ++ ){
     39         f[1][Num][Num] = 1 ;
     40     }
     41 
     42     /*  直接转移情况  */
     43     for( int Len = 2 ; Len <= len ; Len ++ ){
     44         for( int n1 = 0 ; n1 <= 9 ; n1 ++ ){
     45             for( int n2 = 0 ; n2 <= 9 ; n2 ++ ){
     46                 for( int Num = 0 ; Num <= 9 ; Num ++ ){
     47                     f[Len][n1][Num] += f[Len-1][n2][Num];
     48                 }
     49             }
     50             f[Len][n1][n1] += Base[Len];
     51         }
     52     }
     53 
     54 }
     55  
     56  
     57 void solve(){
     58     //For example : 12345
     59     //先处理   0000~9999,保持没有前导零
     60     for(int i = 1 ; i < len ; i++ ){
     61         for(int j = 1 ; j <= 9 ; j ++ ){
     62             for(int Num = 0 ; Num <= 9 ; Num ++ ){
     63                 Ans[Num] += f[i][j][Num];
     64             }
     65         }
     66     }
     67  
     68     //处理上限问题: 1****
     69     for( int i = len ; i >= 1 ; i-- ){
     70         //       1(****)
     71         for( int j = 0 ; j < Str[i]-'0' ; j++ ){
     72             if( i == len && j == 0 ) continue ;
     73             for( int Num = 0 ; Num <= 9 ; Num ++ ){
     74                 Ans[Num] += f[i][j][Num];
     75             }
     76         }
     77  
     78         //      (1)0000 ~ **** 这一部分就是有枚举的后面的位置数字和 +1
     79  
     80         //Ans[Str[i]-'0'] += ( number % Base[i] + 1 );
     81  
     82         number = atoi( (T + 1) + (len-i+1) );
     83         Ans[Str[i]-'0'] += number + 1 ;
     84     }
     85  
     86 }
     87 void Output(){
     88     for(int i=0;i<=9;i++) printf("%lld
    ",Ans[i]);
     89 }
     90 int main()
     91 {
     92     Input();
     93     Init();
     94     solve();
     95     Output();
     96     return 0;
     97 }
     98  
     99  
    100 /*
    101  
    102 123456789
    103  
    104 96021948
    105 130589849
    106 100589849
    107 96589849
    108 96089849
    109 96029849
    110 96022849
    111 96022049
    112 96021959
    113 96021949
    114  
    115 21
    116  
    117 2
    118 13
    119 4
    120 2
    121 2
    122 2
    123 2
    124 2
    125 2
    126 2
    127  
    128 987654321
    129  
    130 780521262
    131 891632373
    132 891632364
    133 891632284
    134 891631584
    135 891625584
    136 891575584
    137 891175584
    138 888175584
    139 868175584
    140 */
    View Code
     
  • 相关阅读:
    关于《GridView“GridView1”激发了未处理的事件“PageIndexChanging”》的问题!
    励志名言
    Java从入门到精通
    Java学习每天进步一点点
    学**况
    git常用命令
    linux常用命令
    linux yum命令详解
    git分支
    linux常用命令(2)
  • 原文地址:https://www.cnblogs.com/Osea/p/11437386.html
Copyright © 2020-2023  润新知