• 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;
    }
  • 相关阅读:
    Linux系统教程:设置GRUB菜单密码
    vimdiff的常用命令
    Zero-Copy实现原理
    解决业务代码里的分布式事务一致性问题
    用好这6个APP,学英语SO EASY!
    线程池调优
    理解select,poll,epoll实现分析
    时序图
    性能监控-TP理解
    sshd_config OpenSSH SSH 进程配置文件配置说明
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5212607.html
Copyright © 2020-2023  润新知