题目大意:给出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;
}