fzoj 2113数位dp

参考http://blog.csdn.net/xingyeyongheng/article/details/8785785

#include<stdio.h>
#define ll long long
#define N 20
ll dp[N];//dp[N]记录长度为i的一的个数
ll power(ll a) {
 ll sum=1,i;
 for(i=1;i<=a;i++)
    sum*=10;
 return sum;
}
void init() {
    ll i;
    dp[1]=1;
    for(i=2;i<=19;i++) 
     dp[i]=dp[i-1]*10+power(i-1);//长度为i-1的的1的个数前面加上任意的一个数也一定含有一,在加上首项为1的任意数
}
ll slove(ll  x) {
   ll to=0,i,k=0,a[N],flag=0;
   while(x) {
    a[++k]=x%10;
    x/=10;
   }
   a[k+1]=0;
   for(i=k;i>=1;i--) {
   to=to+a[i]*dp[i-1];//记录有几个长度为i-1的数
   if(flag)to=to+a[i]*flag*power(i-1);//如果前面已经有1了就把后面的任意数都算进去
    if(a[i]>1)to=to+power(i-1);//如果大于1那么就有以1开头的任意数也要算进去
   if(a[i]==1)flag++;//记录前面1的个数
   }
   return to;
}
int main() {
     ll  a,b;
      init();
      while(scanf("%I64d%I64d",&a,&b)!=EOF) {
        printf("%I64d\n",slove(b+1)-slove(a));
      }
return 0;
}


posted @ 2014-05-08 17:35  HYDhyd  阅读(136)  评论(0编辑  收藏  举报