Description
给出a,b,求出[a,b]中各位数字之和能整除原数的数的个数。
Input
Output
Sample Input
10 19
Sample Output
3
HINT
【约束条件】1 ≤ a ≤ b ≤ 10^18
题解
由于各位数字和只有18*9种,可以枚举和,再数位数位dp。
代码
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<cstring>
typedef long long ll;
using namespace std;
inline int read()
{
int x=0;char ch=getchar();
while (ch<'0'||ch>'9') ch=getchar();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
}
int n,a[21];
ll l,r,f[21][203][203][2];
ll solve(ll x)
{
if (!x) return 0;
n=0;while (x){a[++n]=x%10;x/=10;}
reverse(a+1,a+n+1);ll ans=0;
for (int mod=1;mod<=18*9;mod++)
{
memset(f,0,sizeof(f));
f[0][0][0][1]=1;
for (int i=0;i<n;i++)
for (int j=0;j<=n*9;j++)
for (int k=0;k<=n*9;k++)
for (int l=0;l<2;l++)
if (f[i][j][k][l])
{
for (int t=0;t<=9;t++)
{
if (l&&a[i+1]<t) break;
if (l&&a[i+1]==t) f[i+1][j+t][(k*10+t)%mod][1]+=f[i][j][k][l];
else f[i+1][j+t][(k*10+t)%mod][0]+=f[i][j][k][l];
}
}
ans+=f[n][mod][0][0]+f[n][mod][0][1];
}
return ans;
}
int main()
{
scanf("%lld%lld",&l,&r);
printf("%lld",solve(r)-solve(l-1));
return 0;
}