【算法课】数字统计问题

题目描述

给定一本书,其中包含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\n",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
 

猜你喜欢

转载自www.cnblogs.com/Osea/p/11437386.html