求区间内该数的值模该数的各位数字和为0的数有多少个。
没想到简洁的状态,d[i][s][mod][r]表示i位,前缀和为s,总和为mod,%mod=r的数有多少个。
1 #include <string.h> 2 #include <stdio.h> 3 #include <algorithm> 4 //i位,前缀和为s,总和为mod,%mod=r的数有多少个 5 int num[10], len, ans, sum, d[10][82][82][82]; 6 int dfs(int i, int s, int mod, int r, bool e){ 7 if(mod > 81 || s > mod) return 0; 8 if (i == -1) return s == mod && r == 0; 9 if (!e && d[i][s][mod][r]) return d[i][s][mod][r]; 10 int u = e?num[i]:9, res = 0; 11 for (int x = 0; x <= u; ++x){ 12 res += dfs(i-1, s+x, mod, (r*10+x)%mod, e&&x==u); 13 } 14 return e?res:d[i][s][mod][r] = res; 15 } 16 int get(int x) { 17 ans = 0; 18 for (len = sum = 0; x; num[len++] = x%10, sum += x%10, x/=10); 19 for (int i = 1; i <= len * 9; i++) ans += dfs(len-1, 0, i, 0, 1); 20 return ans; 21 } 22 int cas, a , b; 23 int main(){ 24 //freopen("test.in", "r", stdin); 25 memset(d, -1, sizeof d); 26 scanf("%d", &cas); 27 for (int ca = 1; ca <= cas; ca++){ 28 scanf("%d%d", &a, &b); 29 printf("Case %d: %d\n", ca, get(b) - get(a-1)); 30 } 31 return 0; 32 }