• 热身赛题重现江湖


    热身赛题重现江湖

    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.

    Input

    有若干组数据,每组数据一行。 (输入结束标志应该以EOF为准,当scanf函数的返回值为EOF时,表示已经没有数据可以读了)
    每行一个数字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

    chuyuaem
     

    // 位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 ;
    }
    
  • 相关阅读:
    区分服务器和客户端,玩家的控制权
    分割字符串
    switch语句的使用
    博客暂停使用
    [题解]洛谷P1041 传染病控制
    [题解]洛谷P2668 斗地主
    [题解]洛谷P4017 最大食物链计数
    [题解]洛谷P1983 车站分级
    [OI学习笔记]倍增LCA
    [OI学习笔记]st表
  • 原文地址:https://www.cnblogs.com/20120125llcai/p/3443795.html
Copyright © 2020-2023  润新知