bzoj1833 数字计数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj1833 数字计数相关的知识,希望对你有一定的参考价值。

Description

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

Input

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

Output

输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次。
 
数位dp
c[i]表示长度为i的由0~9组成的串中每个字符的出现次数
F(x)计算与x位数相同且不大于x的数中每个字符的出现次数并累加到答案数组f
#include<cstdio>
typedef long long lint;
lint c[16]={0};
lint p10[16]={1};
lint l,r;
lint f[16];
void F(lint x){
    if(!x)return;
    int v[16],p=0;
    while(x)f[v[++p]=x%10]++,x/=10;
    for(int i=1;i<v[p];i++){
        for(int j=0;j<=9;j++)f[j]+=c[p-1];
        f[i]+=p10[p-1];
    }
    for(int k=p-1;k>=1;k--){
        for(int i=0;i<v[k];i++){
            for(int j=0;j<=9;j++)f[j]+=c[k-1];
            f[i]+=p10[k-1];
            for(int j=p;j>k;j--)f[v[j]]+=p10[k-1];
        }
    }
}
int main(){
    for(int i=1;i<16;i++)p10[i]=p10[i-1]*10;
    for(int i=1;i<16;i++)c[i]=c[i-1]*10+p10[i-1];
    scanf("%lld%lld",&l,&r);
    --l;
    F(l);
    for(int i=0;p10[i]-1<l;i++)F(p10[i]-1);
    for(int i=0;i<16;i++)f[i]=-f[i];
    F(r);
    for(int i=0;p10[i]-1<r;i++)F(p10[i]-1);
    printf("%lld",f[0]);
    for(int i=1;i<=9;i++)printf(" %lld",f[i]);
    return 0;
}

 

以上是关于bzoj1833 数字计数的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1833: [ZJOI2010]count 数字计数(数位DP+记忆化搜索)

bzoj1833 数字计数

bzoj1833: [ZJOI2010]count 数字计数 && codevs1359 数字计数

[BZOJ1833][ZJOI2010]count 数字计数

bzoj 1833 [ZJOI2010]count 数字计数

bzoj1833 [ZJOI2010]count 数字计数