zoukankan      html  css  js  c++  java
  • bzoj 1833: [ZJOI2010]count 数字计数

    Time Limit: 3 Sec Memory Limit: 64 MB
    Submit: 4533 Solved: 2055
    [Submit][Status][Discuss]
    Description

    给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。
    Input

    输入文件中仅包含一行两个整数a、b,含义如上所述。
    Output

    输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次。
    Sample Input

    1 99
    

    Sample Output

    9 20 20 20 20 20 20 20 20 20
    

    HINT

    30%的数据中,a<=b<=10^6;
    100%的数据中,a<=b<=10^12。

    解题思路

    f[i][j][k] 表示i位,开头位j,k这个数出现的次数,先预处理出f数组。细节比较多。

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    const int MAXN = 13;
    typedef long long LL;
    
    LL a,b;
    LL mul[MAXN];
    struct Dight{
        LL a[MAXN];
        Dight(){memset(a,0,sizeof(a));}
    }f[MAXN][MAXN];
    
    Dight operator +(Dight A,Dight B){
        for(register int i=0;i<=9;i++)
            A.a[i]+=B.a[i];
        return A;
    }
    
    Dight operator -(Dight A,Dight B){
        for(register int i=0;i<=9;i++)
            A.a[i]-=B.a[i];
        return A;
    }
    
    inline Dight calc(LL x){
        Dight sum;
        sum.a[0]=1;
        if(x==0) return sum;
        int len=13;
        while(x<=mul[len]) len--;
        for(register int i=1;i<len;i++) 
            for(register int j=1;j<=9;j++)
                sum=sum+f[i][j];
        int cur=x/mul[len];
        for(register int i=1;i<cur;i++)
            sum=sum+f[len][i];
        x%=mul[len];sum.a[cur]+=x+1;
        for(register int i=len-1;i;i--){
            cur=x/mul[i];
            for(register int j=0;j<cur;j++)
                sum=sum+f[i][j];
            x%=mul[i];
            sum.a[cur]+=x+1;
        }
        return sum;
    }
    
    int main(){
        scanf("%lld%lld",&a,&b);
        mul[1]=1;
        for(register int i=2;i<=13;i++) 
            mul[i]=mul[i-1]*10ll;
        for(register int i=0;i<=9;i++)
            f[1][i].a[i]=1;
        for(register int i=2;i<=12;i++) 
            for(register int j=0;j<=9;j++)
                for(register int k=0;k<=9;k++){
                    f[i][j]=f[i][j]+f[i-1][k];
                    f[i][j].a[j]+=mul[i-1];
                }
    //  for(register int i=1;i<=2;i++)  
    //      for(register int j=0;j<=9;j++)
    //          for(register int k=0;k<=9;k++)
    //              printf("f[%d][%d][%d]=%d
    ",i,j,k,f[i][j].a[k]);            
        Dight ans=calc(b)-calc(a-1);
        for(register int i=0;i<=9;i++)
            printf("%lld ",ans.a[i]);
    }
  • 相关阅读:
    潭州课堂25班:Ph201805201 第十二课 new方法,定制属性访问,描述符与装饰器 (课堂笔记)
    潭州课堂25班:Ph201805201 第十一课 继承,多继承和魔术方法,属性和方法 (课堂笔记)
    Storm笔记
    java代码。继承。。。很戳我的心啊。。不太懂。super的真正用法
    java代码。从来没想过java里的继承是多么的难懂。如哲学
    java代码继承疑惑,请有心人解答
    java冒泡排序
    java数组复制
    java继承。顾不了
    java继承初级
  • 原文地址:https://www.cnblogs.com/sdfzsyq/p/9676918.html
Copyright © 2011-2022 走看看