大致题意:
问在区间[a,b]内有多少个整数满足被K整除,且这个数的每一位上数字的和也被K整除
a , b <= 2^31
思路:
显然在int范围内,每位数字之和不超过9*10 ,所以K大于100就直接返回0, 其余用数位dp算
数位dp的大致思路都一样,先dp出dp[len][x][y] 表示len位长的数有多少个数modK等于x,每一位和modK等于y
然后求DP(int num) 表示 不超过num 有多少个满足题意的数,输出DP(b) - DP(a-1) 就好
//#pragma comment(linker, "/STACK:1024000000,1024000000") #include <iostream> #include <cstring> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #include <string> #include <vector> #include <cstdio> #include <ctime> #include <bitset> #include <algorithm> #define SZ(x) ((int)(x).size()) #define ALL(v) (v).begin(), (v).end() #define foreach(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++ i) #define reveach(i, v) for (__typeof((v).rbegin()) i = (v).rbegin(); i != (v).rend(); ++ i) #define REP(i,n) for ( int i=1; i<=int(n); i++ ) #define rep(i,n) for ( int i=0; i< int(n); i++ ) using namespace std; typedef long long ll; #define X first #define Y second #define PB push_back #define MP make_pair typedef pair<int,int> pii; template <class T> inline bool RD(T &ret) { char c; int sgn; if (c = getchar(), c == EOF) return 0; while (c != '-' && (c<'0' || c>'9')) c = getchar(); sgn = (c == '-') ? -1 : 1 , ret = (c == '-') ? 0 : (c - '0'); while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return 1; } template <class T> inline void PT(T x) { if (x < 0) putchar('-') ,x = -x; if (x > 9) PT(x / 10); putchar(x % 10 + '0'); } const int N = 16; int a, b, K; ll dp[N][123][123]; // x - > *mod; y - > summod ll p[N]; int bit[N]; ll DP(int x) { int t = x; int top = 0; ll ans = 0; int sum = 0; while( t ) bit[++top] = t % 10 , t /= 10 , sum += bit[top]; ll curx = 0, cury = 0; for(int i = top; i >= 1; i -- ) { for(int dig = 0; dig < bit[i]; dig ++ ) { ll nx = ( K - ( curx + dig * p[i] ) % K ) % K; ll ny = ( K - ( cury + dig ) % K ) % K; ans += dp[i-1][nx][ny]; } curx = (curx + bit[i] * p[i] ) % K; cury = (cury + bit[i] ) % K; } return ans + ( sum % K == 0 && x % K == 0 ); } int main() { p[1] = 1; for(int i = 2; i < N; i ++ ) p[i] = 10 * p[i-1]; int T; RD(T); while(T --) { memset( dp, 0, sizeof(dp)) ; scanf("%d%d%d", &a, &b, &K); if( K >= 100 ) { puts("0"); continue; } dp[0][0][0] = 1; rep(i, 15 ) { rep(j, K ) rep( k, K ) { rep(dig, 10) { ll x = ( dig * p[i + 1] + j ) % K; ll y = ( dig + k ) % K ; dp[i+1][x][y] += dp[i][j][k] ; } } } PT( DP(b) - DP(a - 1) ); puts(""); } }