题目大意:给出a,b,问从a到b之间,有多少个好数字,好数字的定义为:每个位的数字相加是10的倍数。
解题思路:dp[i][j]表示第i位,前i-1位的和为j(j可以从200简化成10,以为只需要考虑最后的数是否是10的倍数即可)有多少个数,需要注意的就是恰好为b的情况,所以要有一个跟踪值s。
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; typedef long long ll; const int N = 20; int c, t[N]; ll dp[N][N]; void cat (ll u) { c = 0; while (u) { t[c++] = u%10; u /= 10; } for (int i = 0; i < c/2; i++) swap(t[i], t[c-i-1]); } ll solve (ll u) { if (u < 0) return 0; else if (u == 0) return 1; memset(dp, 0, sizeof(dp)); cat(u); int s = 0; for (int i = 1; i <= c; i++) { for (int j = 0; j < 10; j++) { for (int k = 0; k < 10; k++) dp[i][(j+k)%10] += dp[i-1][j]; } for (int k = 0; k < t[i-1]; k++) dp[i][(s+k)%10] += 1; s = (s + t[i-1]) % 10; } return dp[c][0] + (s == 0 ? 1 : 0); } int main () { int cas; scanf("%d", &cas); for (int i = 1; i <= cas; i++) { ll a, b; cin >> a >> b; printf("Case #%d: ", i); cout << solve(b) - solve(a-1) << endl; } return 0; }