U - Investigation
思路: 求在两个数n和m之间能够整除k,并且所有位数之和也能整除k的数的数量。拿出两个状态,这个数字和每位数来讨论就可以了。
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
using namespace std;
int k;
int bit[20];
int dp[20][100][100][2];
int dfs(int pos,int ge,int sum,int k,int limit)
{
if(pos==-1)
return !ge&&!sum;
if(!limit&&dp[pos][ge][sum][limit]!=-1)
return dp[pos][ge][sum][limit];
int tmp=0;
int up=limit?bit[pos]:9;
for(int i=0;i<=up;i++)
{
tmp+=dfs(pos-1,(ge+i)%k,(sum*10+i)%k,k,limit&&(i==bit[pos]));
}
if(!limit)
dp[pos][ge][sum][limit]=tmp;
return tmp;
}
int cal(int x)
{
int pos=0;
while(x)
{
bit[pos++]=x%10;
x/=10;
}
return dfs(pos-1,0,0,k,1);
}
int main()
{
int t;
int n,m;
int ans;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{ memset(dp,-1,sizeof(dp));
scanf("%d%d%d",&n,&m,&k);
if(k>=95)ans=0;
else ans=cal(m)-cal(n-1);
printf("Case %d: %d\n",i,ans);
}
return 0;
}