Time Limit: 2 second(s) | Memory Limit: 32 MB |
An integer is divisible by 3 if the sum of its digits is also divisible by 3. For example, 3702 is divisible by 3 and 12 (3+7+0+2) is also divisible by 3. This property also holds for the integer 9.
In this problem, we will investigate this property for other integers.
Input
Input starts with an integer T (≤ 200), denoting the number of test cases.
Each case contains three positive integers A, B and K (1 ≤ A ≤ B < 231 and 0 < K < 10000).
Output
For each case, output the case number and the number of integers in the range [A, B] which are divisible by K and the sum of its digits is also divisible by K.
Sample Input | Output for Sample Input |
3 1 20 1 1 20 2 1 1000 4 | Case 1: 20 Case 2: 5 Case 3: 64 |
题意:给定A,B,k,求区间[A,B]之间各位数字总和能被k整除且本身也能被k整数的个数。
思路:设dp[pos][mod][mod1] 表示当前考虑pos位,之前各位数字总和对k取余为mod、本身对k取余的mod1时,(pos+1)个数位与之前数位组合能够满足条件的个
数。
注意:(1) A,B均小于2^32-1,那么各位总和最多不超过90,那么当k大于90,就直接输出0; (2)memset(dp,-1,sizeof(dp))必须放在里面,因为每次取模的k不一样。
详见代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=15;
int n,m,k;
int bit[MAXN],dp[MAXN][10*MAXN][10*MAXN];
int dfs(int pos,int mod,int mod1,int flag)
{
if(pos == -1 ) return mod == 0 && mod1 == 0;
if(flag && dp[pos][mod][mod1]!=-1) return dp[pos][mod][mod1];
int ans=0;
int x=flag ? 9 : bit[pos];
for(int i=0;i<=x;i++){
int s=(mod+i)%k,t=(mod1*10+i)%k;
ans+=dfs(pos-1,s,t,flag || i<x);
}
if(flag) dp[pos][mod][mod1]=ans;
return ans;
}
int solve(int x)
{
int len=0;
if(!x)
bit[len++]=0;
while(x)
{
bit[len++]=x%10;
x/=10;
}
return dfs(len-1,0,0,0);
}
int main()
{
//freopen("text.txt","r",stdin);
int T,kase=0;
scanf("%d",&T);
while(T--)
{
memset(dp,-1,sizeof(dp));
kase++;
printf("Case %d: ",kase);
scanf("%d%d%d",&n,&m,&k);
if(k>90){
printf("0\n");
continue;
}
printf("%d\n",solve(m)-solve(n-1));
}
return 0;
}