[洛谷P2657][SCOI2009]windy数

题目大意:不含前导零且相邻两个数字之差至少为$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;
}

  

原文地址:https://www.cnblogs.com/Memory-of-winter/p/9287860.html