1042 数字0-9的数量【数位dp】

来源:互联网 发布:gps pf11导航仪端口 编辑:程序博客网 时间:2024/06/05 08:15


点击打开链接


给出一段区间a-b,统计这个区间内0-9出现的次数。
比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次。
Input
两个数a,b(1 <= a <= b <= 10^18)
Output
输出共10行,分别是0-9出现的次数
Input示例
10 19
Output示例
11111111111

题解:和前面1009 一样,但是求0的个数的时候会多出来很多,减去多出来的数即可。


#include<bits/stdc++.h>#define ll long longusing namespace std;const int maxn=510;ll f[22],c[22];void init(){    ll t=1;    for(int i=1;i<=20;++i){        f[i]=i*t;        c[i]=t;        t*=10;    }}ll get(ll x,int num){    ll ret=0,t=1,cnt=0,q,s,tx=x;    while(x){        cnt++;        q=x%10;        s=q;        x/=10;        ret+=s*f[cnt-1];        if(s>num) ret+=c[cnt];        else if(s==num) ret+=t;        t+=q*c[cnt];        q*=c[cnt];    }    if(num==0){  //除去多余的0        t=1;        while(tx){            ret-=t;            t*=10;            tx/=10;        }    }    return ret;}int main(){    ll l,r;    init();    while(~scanf("%lld%lld",&l,&r)){        for(int i=0;i<10;++i)            printf("%lld\n",get(r,i)-get(l-1,i));    }    return 0;}



看网上一个人的代码很精简,


#include <iostream>  #include<bits/stdc++.h>  #define ll long long  using namespace std;    void dfs(ll a,ll b,ll c[])  {      ll n=a/10,m=a%10,t=n;      for(int i=0;i<=m;i++)   c[i]+=b;//当前位对低位的影响      for(int i=0;i<10;i++)   c[i]+=b*n;//高位对低位的影响      c[0]-=b;//0特殊处理,将多算的0减去      while(t)//当前位对高位的影响      {          c[t%10]+=b*(m+1);//加上0          t/=10;      }      if(n)   dfs(n-1,b*10,c);//n已经处理过,所以要处理n-1  }    ll x[20],y[20];    int main()  {      ll a,b;      cin>>a>>b;      dfs(a-1,1,x);      dfs(b,1,y);      for(int i=0;i<10;i++)   cout<<y[i]-x[i]<<endl;  }  



原创粉丝点击