题目大意:不含前导零且相邻两个数字之差至少为$2$的正整数被称为$windy$数。问$[A, B]$内有多少个$windy$数?
题解:$f_{i, j}$表示数有$i$位,最高位为$j$(可能为$0$),$f_{i, j} = sumlimits_{0 leq k leq 9, |k - j| > 2} f_{i - 1, k}$
然后求出$[0, A)$和$[0, B]$分别有多少个$windy$数,相减即可
卡点:无
C++ Code:
#include <cstdio> using namespace std; int f[11][11], a, b; int num[11], cnt, ans; int abs(int x) {return x > 0 ? x : -x;}; int work(int x) { cnt = ans = 0; while (x) num[++cnt] = x % 10, x /= 10; for (int i= cnt - 1; i; i--) for (int j = 1; j < 10; j++) ans += f[i][j]; num[cnt+1] = -2; for (int i = cnt; i; i--) { for (int j = 0; j < num[i]; j++) if (abs(num[i+1] - j) >= 2) ans += f[i][j]; if (abs(num[i] - num[i+1]) < 2) break; } return ans; } int main() { scanf("%d%d", &a, &b); for (int i = 1; i <= 10; i++) for (int j = 0; j < 10; j++) if (i == 1) f[i][j] = 1; else for (int k = 0; k < 10; k++) if (abs(j - k) >= 2) f[i][j] += f[i - 1][k]; int res = work(b + 1) - work(a); printf("%d ", res); return 0; }