比较直接的数位dp,但不是很好写
注:
1、每一位作为最高位的时候要统计
2、每一位一个周期的个数要统计
3、每一位作为不确定的最高位的个数要统计
4、统计分两部分:当前位和以后位
码:
#include<iostream>
#include<cstdio>
using namespace std;
long long cnt,a,b,ans,daan[11],now,i,lina,linb,jx[22];
long long pow(int a,int b)
{long long ans=1,i;
for(i=1;i<=b;i++)ans=ans*a;
return ans;
}
void dfs(int wei,int mb)
{
int o=now/pow(10,wei-1)%10;
if(wei==cnt)
{
if(cnt==1)
{
if(o>=mb)ans=1;
return;
}
ans+=(o-1)*jx[wei-1];
if(o>mb&&mb!=0)ans+=pow(10,wei-1);
if(o==mb&&mb!=0)ans+=now%(pow(10,wei-1))+1;
return;
}
if(wei>1)
{
if(mb!=0)
{
ans+=jx[wei-1]*9+pow(10,wei-1); //不算前导0
}
else
{
ans+=jx[wei-1]*9;
}
jx[wei]=jx[wei-1]*10+pow(10,wei-1);//往前进还是有前导0的
}else //个位直接算
{
ans++;
jx[wei]=1;
}
dfs(wei+1,mb);
ans+=o*jx[wei-1];
if(o>mb)ans+=pow(10,wei-1);
if(o==mb)ans+=now%(pow(10,wei-1))+1;
}
int main()
{
scanf("%lld%lld",&a,&b);
a--;
long long linaa=a,linbb=b;
while(linaa)
{
linaa/=10;
lina++;
}
while(linbb)
{
linbb/=10;
linb++;
}
for(i=0;i<=9;i++)
{
now=b;ans=0;cnt=linb;
dfs(1,i);
daan[i]+=ans;
if(a!=0)
{
now=a;ans=0;cnt=lina;
dfs(1,i);
daan[i]-=ans;
}else if(i==0)daan[i]--;
}
for(i=0;i<=9;i++)
{
printf("%lld ",daan[i]);
}
}