简介:
a~b中能被n整除且数字根也能被n整除的数的个数
分析:
一眼数位dp
于是我就开始设计状态:f[i][j][p][q][0/1],表示第i位,填的数字是j,余数为p,数字根余数为q,卡不卡边界
这是我看到了k的范围
完了,开不下啊怎么办
然而,实际上
k最大值不超过90
因为2^31只有10位,即使都填9,得到的数字根也不超过90
(差点被歪国人骗了)
tip
认真分析数据的范围
题目给出的不一定准确
注意a==1的情况
//这里写代码片
#include<cstdio>
#include<cstring>
#include<iostream>
#define ll long long
using namespace std;
ll f[11][10][100][100][2];
ll n,m,k;
int a[11],b[11];
void cl(ll n,int *a)
{
int tt=0;
while (n)
{
a[++tt]=n%10;
n/=10;
}
for (int i=1;i<=tt/2;i++) swap(a[i],a[tt-i+1]);
a[0]=tt;
}
ll doit(int *a)
{
memset(f,0,sizeof(f));
int i,j,p,q,l,c;
for (i=0;i<=a[1];i++) f[1][i][i%k][i%k][i==a[1]]=1;
for (i=1;i<a[0];i++)
for (j=0;j<=9;j++)
for (p=0;p<k;p++)
for (q=0;q<k;q++)
for (l=0;l<=1;l++)
if (f[i][j][p][q][l])
{
int tt=9;
if (l) tt=a[i+1];
for (c=0;c<=tt;c++)
{
int p1=(p*10+c)%k; //number
int q1=(q+c)%k; //root of number
f[i+1][c][p1][q1][c==a[i+1]&&l]+=f[i][j][p][q][l];
}
}
ll ans=0;
for (i=0;i<=9;i++)
for (j=0;j<=1;j++)
ans+=f[a[0]][i][0][0][j];
return ans;
}
int main()
{
int T;
scanf("%d",&T);
while (T--)
{
scanf("%lld%lld%lld",&n,&m,&k);
if (k>90)
{
printf("0\n");
continue;
}
n--;
cl(n,a); cl(m,b);
if (n==0) a[0]++;
printf("%lld\n",doit(b)-doit(a));
}
return 0;
}