YBT高效进阶 5.3.3 数字计数
思路
注意用unsigned long long
用二维表示状态:当前位,已经找到的个数
如果枚举的数==要找的数,没有前导0,ans+1
CODE
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
unsigned long long f[110][110],s[110],power[110];
unsigned long long digitDP(unsigned long long dep,unsigned long long digit,bool limit,bool zero,unsigned long long sum)
{
if(!dep)return sum;
if(!limit&&!zero&&f[dep][sum]!=-1)return f[dep][sum];
unsigned long long i,ans=0,mx=limit?s[dep]:9;
for(i=0;i<=mx;i++)
ans+=digitDP(dep-1,digit,(i==mx)&limit,(i==0)&zero,sum+((!(i==0&&zero))&&(i==digit)));
if(!limit&&!zero)f[dep][sum]=ans;
return ans;
}
unsigned long long solve(unsigned long long x,unsigned long long y)
{
unsigned long long sum;
if(!x)return 0;
for(sum=0;x;s[++sum]=x%10,x/=10);
memset(f,-1,sizeof(f));
return digitDP(sum,y,1,1,0);
}
int main()
{
unsigned long long l,r,i;
scanf("%llu%llu",&l,&r);
for(power[0]=1,i=1;i<=13;power[i]=power[i-1]*10,++i);
for(i=0;i<10;++i)printf("%llu ",solve(r,i)-solve(l-1,i));
return 0;
}