数位DP入门题。
然而没有个讲解蒟蒻我真心看不懂。
推荐好的讲解一份——点我
代码(递推)
#include <cstdio> #include <cstring> int n, m, f[10][10], digit[10]; inline void init() { int i, j, k; f[0][0] = 1; for (i = 1; i <= 7; i++) for (j = 0; j <= 9; j++) for (k = 0; k <= 9; k++) if (j != 4 && !(j == 6 && k == 2)) f[i][j] += f[i - 1][k]; } inline int calc(int x) { int i, j, ans = 0; memset(digit, 0, sizeof(digit)); for (digit[0] = 0; x; x /= 10) digit[++digit[0]] = x % 10; for (i = digit[0]; i; i--) { for (j = 0; j < digit[i]; j++) if (j != 4 && !(j == 2 && digit[i + 1] == 6)) ans += f[i][j]; if (digit[i] == 4 || (digit[i] == 2 && digit[i + 1] == 6)) break; } return ans; } int main() { init(); while (scanf("%d %d", &n, &m), (n || m)) printf("%d ", calc(m + 1) - calc(n)); return 0; }
代码(记忆化搜索)
#include <cstdio> #include <cstring> #include <iostream> int f[10][3], digit[10]; inline int dfs(int pos, bool sta, bool limit) { if (!pos) return 1; if (!limit && f[pos][sta] ^ -1) return f[pos][sta]; int i, tmp = 0, up = limit ? digit[pos] : 9; for (i = 0; i <= up; i++) { if ((sta && i == 2) || i == 4) continue; tmp += dfs(pos - 1, i == 6, limit && i == digit[pos]); } if (!limit) f[pos][sta] = tmp; return tmp; } inline int solve(int x) { for (digit[0] = 0; x; x /= 10) digit[++digit[0]] = x % 10; return dfs(digit[0], 0, 1); } int main() { int x, y; memset(f, -1, sizeof(f)); while (~scanf("%d %d", &x, &y) && x + y) printf("%d ", solve(y) - solve(x - 1)); return 0; }