数位dp即可
定义\(f[i][j]\)为\(i\)为数以\(j\)开头的符合条件的个数
状态转移方程\(f[i][j]=\sum_{k=0}^9f[i-1][k](\left|j-k\right|\ge2)\)
具体实现见代码
#include<bits/stdc++.h>
using namespace std;
int f[12][12] = {0};
int a,b;
int lena = 0,lenb = 0;
int ac[12],bc[12];
int ans = 0;
int cnt[12] = {0};
int main(){
scanf("%d%d",&a,&b);
b++;
for(int i = 0;i<10;i++) f[1][i] = 1;
int res = a;
while(res){
ac[++lena] = res%10;
res/=10;
}
res = b;
while(res){
bc[++lenb] = res%10;
res/=10;
}
ac[lena+1] = -19260817;
bc[lenb+1] = -19260817;
for(int i = 2;i<=lenb;i++){
for(int j = 0;j<10;j++)
for(int k = 0;k<10;k++)
if(abs(j-k)>=2)
f[i][j] += f[i-1][k];
cnt[i] = cnt[i-1];
for(int j =1;j<10;j++){
cnt[i] += f[i-1][j];
}
}
ans += cnt[lenb]-cnt[lena];
bool flag = 0;
for(int i = lenb;i;i--){
for(int j = 0;j<bc[i];j++){
if(i==lenb&&j==0) continue;
if(abs(j-bc[i+1])>=2){
ans += f[i][j];
}
}
if(abs(bc[i]-bc[i+1])<2) break;
}
for(int i = lena;i;i--){
for(int j = 0;j<ac[i];j++){
if(i==lena&&j==0) continue;
if(abs(j-ac[i+1])>=2) ans -= f[i][j];
}
if(abs(ac[i]-ac[i+1])<2) break;
}
printf("%d",ans);
return 0;
}