给定整数 A ,B ,K 求 区间[A, B] 中被 K 整除且各位数之和被 K 整除的数有多少个,1 <= A <= B < 2^31 且 0< K < 10000
package UVa11361;
import java.util.Scanner;
public class Main {
private static final int MAX_BIT = 16;
private static final int MAX_K = 128;
// g[i][p][q] 为所有 i 位数 [00...0 - 99...9] 中,各位数和模 k 为 p 且数本身模 k 为 q 的数的个数
private int[][][] g = new int[MAX_BIT][MAX_K][MAX_K];
// f[i][m][n] 为所有 i 位数中,小于等于 A 的 前i 位数(从低到高),各位数和模 k 为 p 且数本身模 k 为 q 的数的个数
private int[][][] f = new int[MAX_BIT][MAX_K][MAX_K];
// for d = 0..9, g[i][m][n] -> g[i+1][(m+d)%k][(d*10^i+n)%k]
// for d = 0..A[i]-1, g[i][m][n] -> f[i+1][(m+d)%k][(d*10^i+n)%k]
// for d = A[i], f[i][m][n] -> f[i+1][(m+d)%k][(d*10^i+n)%k]
public int solve(int n, int k) {
if ( k > MAX_K ) return 1;
// 初始化 g,f 数组
for ( int i=0; i<MAX_BIT; i++ ) {
for ( int p=0; p<k; p++ ) {
for ( int q=0; q<k; q++ ) {
g[i][p][q] = f[i][p][q] = 0;
}
}
}
int Di = n%10, i = 1, Pi = 1;
n /= 10;
// 利用所有 1 位数 [0..9] 初始化 g 和 f
for ( int x=0; x<=9; x++) g[1][x%k][x%k]++;
for ( int x=0; x<=Di; x++ ) f[1][x%k][x%k]++;
while ( n > 0 ) {
i++; Di = n%10; Pi *=10; n/=10;
// 将第 i-1 位累积到 i 位
for ( int x=0; x<=9; x++ ) {
for ( int p=0; p<k; p++ ) {
for ( int q=0; q<k; q++ ) {
g[i][(p+x)%k][(q+x*(Pi%k))%k] += g[i-1][p][q];
if ( x < Di ) {
f[i][(p+x)%k][(q+x*(Pi%k))%k] += g[i-1][p][q];
} else if ( x == Di ) {
f[i][(p+x)%k][(q+x*(Pi%k))%k] += f[i-1][p][q];
}
}
}
}
}
return f[i][0][0];
}
public static void main(String[] args) {
Main inst = new Main();
Scanner in = new Scanner(System.in);
int count = in.nextInt();
for ( int i=0; i<count; i++ ) {
int a = in.nextInt();
int b = in.nextInt();
int k = in.nextInt();
int r = inst.solve(b,k) - inst.solve(a-1,k);
System.out.println(r);
}
}
}