#include <bits/stdc++.h>
using namespace std;
const int N = 15;
int a[N];
int dp[N][N];
/**
*
* @param pos 当前位置
* @param pre 前一位数位的数字是多少
* @param lead 本位是不是需要考虑前导0
* @param limit 是否贴着上界
* @return
*/
int dfs(int pos, int pre, bool lead, bool limit) {
if (pos == -1) return 1;
if (!limit && !lead && ~dp[pos][pre]) return dp[pos][pre];//注意模板变化
int res = 0, up = limit ? a[pos] : 9;
for (int i = 0; i <= up; i++)
if (abs(pre - i) >= 2) { //这里根据题意变化
bool st = lead && !i;
/*
如果此位置还在要求考虑前导0,表示之前就没有出现过非0数字,并且本位置填充的依然是0
那么
(1)lead = st 下一数位依然要保持警惕,小心前导0,否则就可以放心大胆的不理这个概念了~
(2)pre = -2
如果不上面的情况,那么 pre直接记录i即可。
*/
res += dfs(pos - 1, st ? -2 : i, st, limit && i == up);
}
return limit ? res : dp[pos][pre] = res;
}
int cal(int x) {
memset(dp, -1, sizeof dp);
int pos = 0;
while (x) a[pos++] = x % 10, x /= 10;
//pre 给初值-2,保证首位是啥都可以
//lead:true 表示第一位也需要考虑是不是前导零,第一位就是0,也不可以
//limit:true : 表示贴上界,不能大于当前的a[pos-1]这一位
return dfs(pos - 1, -2, true, true);
}
int main() {
int l, r;
cin >> l >> r;
cout << cal(r) - cal(l - 1) << endl;
return 0;
}
相关文章: