1 99
9 20 20 20 20 20 20 20 20 20
30%的数据中,a<=b<=10^6;
100%的数据中,a<=b<=10^12。
Emmmmm…………
说实话这个题我是怎么过的我都不知道………………
一共十个数字0,1,2,3,4,5,6,7,8,9,不可能一下子全部算出来,还是先算0再算1这样子遍历每一个数字分开计算
dp[ i ] 表示第 i 位为止的数后面出现了多少个 0 ( or 1,2 ..........9 )
然后就瞎搞
其实这个题对于每一个数码找它出现的次数的思路应该还是蛮清晰的吧。。。。。。
代码:
#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
typedef long long LL;
#define fi first
#define se second
LL dp[20],s[20],t[20];
LL n[20];
LL a,b,m;
LL dfs(LL pos,LL sum,LL num,bool limit)
{
if(pos==-1)
{
if(sum==0&&num==0&&m==0)return 1;
else return 0;
}
if(!limit&&sum>0&&dp[pos]>-1)return dp[pos];
LL up=limit?n[pos]:9;
LL res=0;
for(int i=0;i<=up;i++)
{
LL z=(sum*10+i>0)&&(i==m);
if(limit&&i==up)
{
res+=z*(pos>0?(s[pos-1]+1):1)+dfs(pos-1,sum*10+i,i,true);
}
else
{
res+=z*t[pos]+dfs(pos-1,sum*10+i,i,false);
}
}
if(!limit&&sum>0)dp[pos]=res;
return res;
}
LL solve(LL x)
{
LL len=0;
while(x)n[len++]=x%10,x/=10;
s[0]=n[0];t[0]=1;
LL z=10;
for(int i=1;i<len;i++)s[i]=s[i-1]+n[i]*z,t[i]=z,z*=10;
//for(int i=0;i<len;i++)cout<<s[i]<<' ';puts("");
return dfs(len-1,0,0,true);
}
int main()
{
while(scanf("%lld%lld",&a,&b)!=-1)
{
a--;
for(m=0;m<=9;m++)
{
memset(dp,-1,sizeof(dp));
printf("%lld",solve(b)-solve(a));
if(m<9)putchar(' ');else putchar('\n');
}
}
return 0;
}
大概就是这样了。。。。。
本人蒟蒻,如有错误,还望指正
(虽然今天是8月4号晚了一天的但还是要说果果生日快乐)