链接
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2346
题解
注意到所有数字的和不会超过
90
90
,因此当
K>90
K
>
90
时直接输出
0
0
时,进行数位
DP
D
P
代码
//ÊýλDP
#include <bits/stdc++.h>
#define maxk 100
#define maxn 15
#define cl(x) memset(x,0,sizeof(x))
#define ll long long
using namespace std;
ll N, lim[maxn], f[maxn][maxk][maxk], g[maxn][maxk][maxk], K, mi[maxn];
char a[maxn], b[maxn];
void preprocess()
{
ll i;
mi[1]=1;
for(i=2;i<maxn;i++)mi[i]=mi[i-1]*10;
}
ll dp(char *s)
{
ll i, j, k, x, ans=0;
cl(f), cl(g), cl(lim);
for(i=1;i<=10;i++)lim[i]=s[i];
f[0][0][0]=g[0][0][0]=1;
for(i=0;i<=10;i++)for(j=0;j<=90;j++)for(k=0;k<K;k++)
{
if(f[i][j][k])f[i+1][j+lim[i+1]][(k+lim[i+1]*mi[i+1])%K]+=f[i][j][k];
if(g[i][j][k])
for(x=0;x<=9;x++)
{
g[i+1][j+x][(k+x*mi[i+1])%K]+=g[i][j][k];
if(x<lim[i+1])f[i+1][j+x][(k+x*mi[i+1])%K]+=g[i][j][k];
}
}
for(i=K;i<=90;i+=K)ans+=f[10][i][0];
return ans;
}
int main()
{
ll T, i, la, lb;
preprocess();
scanf("%lld",&T);
while(T--)
{
cl(a), cl(b);
scanf("%s%s%lld",a+1,b+1,&K);
if(K>90){printf("0\n");continue;}
la=strlen(a+1), lb=strlen(b+1);
reverse(a+1,a+la+1);
reverse(b+1,b+lb+1);
for(i=1;i<=la;i++)a[i]-=48;
for(i=1;i<=lb;i++)b[i]-=48;
a[1]--;
for(i=1;i<=strlen(a+1);i++)if(a[i]<0)a[i]+=10, a[i+1]--;
printf("%lld\n",dp(b)-dp(a));
}
return 0;
}