热身赛题重现江湖
Time Limit : 3000/1000ms (Java/Other) Memory Limit : 65535/32768K (Java/Other)
Total Submission(s) : 13 Accepted Submission(s) : 4
Font: Times New Roman | Verdana | Georgia
Font Size: ← →
Problem Description
曾经有人问我,正式比赛会不会有跟热身赛一样的题。我当时说这是个坑。嗯,没错,坑一次。反正,你们都没有在比赛结束后好好思考过这道题吧~~啦啦啦~~啦啦啦~~
一本书的页面从自然数1开始顺序编码直到自然数n。书的页码按照n的位数编排,不足时补充前导数字0。例如,n是149时,第6页用数字006表示,而不是06或6。现在要求你对给定书的总页码n,计算出书的全部页码分别用到多少次数字0,1,2,...,9.
一本书的页面从自然数1开始顺序编码直到自然数n。书的页码按照n的位数编排,不足时补充前导数字0。例如,n是149时,第6页用数字006表示,而不是06或6。现在要求你对给定书的总页码n,计算出书的全部页码分别用到多少次数字0,1,2,...,9.
Input
有若干组数据,每组数据一行。 (输入结束标志应该以EOF为准,当scanf函数的返回值为EOF时,表示已经没有数据可以读了)
每行一个数字n。(1≤n≤10^9)
每行一个数字n。(1≤n≤10^9)
Output
每组输入数据对应10行。分别是0-9的使用次数。
输出完一组数据后,额外输出一个换行。
输出完一组数据后,额外输出一个换行。
Sample Input
11 1
Sample Output
10 4 1 1 1 1 1 1 1 1 0 1 0 0 0 0 0 0 0 0
Author
// 位dp ,dp[i][j][k] ,表示 长度 为 i , 以 j 开头 , k 用的次数
// dp[i][j][k] = dp[i-1][u][k] ,如果 j == k ,则还要加上 tt = 10^(i-1) ;
#include <cstdio> #include <cstring> #include <iostream> #include <queue> #include<algorithm> #define maxn 20 #define LL long long #define mod 1000000007 using namespace std; LL dp[maxn][maxn][12] ;// len , kaitou , ans int bit[16] ; void init() { int i , j , k , u , tt = 10 ; memset(dp,0,sizeof(dp)) ; for( i = 0 ; i <= 9; i++) dp[1][i][i] = 1 ; for( i = 2 ; i <= 11 ;i++ ){ for( j = 0 ; j <= 9 ;j++ ) { for( k = 0 ; k <= 9 ;k++ ) for( u = 0 ; u <= 9 ;u++ ) dp[i][j][k] += dp[i-1][u][k] ; dp[i][j][j] += tt ; } tt *= 10 ; } } void getans( int n ) { int i , len = 0 ,k , j ; int a[13] = {0}; LL tt = 1 , ans[13] = {0}; // tt 必须是 long long ,因为10^9 时 len = 10 ,但是 tt 计算了11 次 memset(ans,0,sizeof(ans)) ; a[1] = 0 ; k = n ; while(n) { bit[++len] = n%10 ; n /= 10 ; tt *= 10 ; } tt /= 10 ; for( i = len ; i > 1 ;i--) { k = k%tt ; a[i] = k ; tt /= 10 ; } for( i = len ; i >= 1 ;i-- ) { for( k = 0 ; k < bit[i] ; k++ ) { for( j = 0 ; j <= 9 ;j++ ) ans[j] += dp[i][k][j] ; } ans[bit[i]] += a[i]+1 ; } cout << ans[0]-len << endl; // 我们计算的时候把0页码算进去了,所以要把00..00(len 个)去掉 for( i = 1 ;i <= 9 ;i++ ) cout << ans[i] << endl; } int main() { int i , j ,L , k ; int n ; init() ; //freopen("g.in","r",stdin); while( scanf("%d" , &n ) != EOF ) { getans(n) ; puts("") ; } return 0 ; }