又是一道数位dp。。。
f[len][st]表示 长度为len的、以st为开头的数中含有多少个数字dig。
init和solve部分又一次出现了。上一篇数位dp中也用的是同样方法。同样,注意细节!!!
#include<stdio.h>
#include<string.h>
typedef long long ll;
ll a,b;
ll f[20][12];
ll quick(int x,int y)
{
ll sum=1;
while(y)
{
if(y%2==1)
{
sum*=x;
}
x*=x;
y/=2;
}
return sum;
}
void init(int dig)
{
memset(f,0,sizeof(f));
for(int i=0;i<=9;i++)
{
if(i==dig)
{
f[1][i]=1;
}else
{
f[1][i]=0;
}
}
for(int len=2;len<=12;len++)
{
for(int i=0;i<=9;i++)
{
for(int j=0;j<=9;j++)
{
f[len][i]+=f[len-1][j];
}
if(i==dig)
{
f[len][i]+=quick(10,len-1);
}
}
}
}
int num[20];
ll solve(ll x,int dig)
{
if(x==0)return 0;
int len=0;
ll root=x;
while(x)
{
num[++len]=x%10;
x/=10;
}
ll ans=0;
for(int i=1;i<len;i++)
{
for(int j=1;j<=9;j++)
{
ans+=f[i][j];
}
}
for(int i=1;i<num[len];i++)
{
ans+=f[len][i];
}
if(num[len]==dig)
{
ans+=root%quick(10,len-1)+1;
}
for(int i=len-1;i>=1;i--)
{
for(int j=0;j<num[i];j++)
{
ans+=f[i][j];
}
if(num[i]==dig)
{
ans+=root%quick(10,i-1)+1;
}
}
return ans;
}
int main()
{
scanf("%lld %lld",&a,&b);
for(int i=0;i<=9;i++)
{
init(i);
if(i==0)
{
printf("%lld",solve(b,i)-solve(a-1,i));
}else
{
printf(" %lld",solve(b,i)-solve(a-1,i));
}
}
}