在区间内统计任意两位相差大于二的数的个数。数位dp在推到时候注意最高位要特判一下因为最高位是没有前一位的。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <cstdlib> 6 #include <algorithm> 7 #define ll long long 8 #define LEN 100 9 10 using namespace std; 11 12 ll dp[LEN][LEN]; 13 14 inline int abs(int x){return x>0?x:-x;} 15 16 void init() 17 { 18 memset(dp, 0, sizeof dp); 19 for(int i=0; i<LEN; i++)dp[1][i] = 1; 20 for(int i=2; i<LEN; i++){ 21 for(int j=0; j<10; j++){ 22 for(int k=0; k<10; k++){ 23 if(abs(j-k)<2)continue; 24 dp[i][j] += dp[i-1][k]; 25 } 26 } 27 } 28 } 29 30 ll solve(ll x){ 31 if(!x)return 0; 32 ll ret = 0; 33 int str[LEN] = {0}; 34 int len = 0; 35 while(x){ 36 str[++len] = x%10; 37 x/=10; 38 } 39 bool flag = true; 40 for(int i=1; i<len; i++){ 41 for(int j=1; j<=9; j++){ 42 ret+=dp[i][j]; 43 } 44 } 45 for(int i=len; i>=1; i--){ 46 for(int j=0; j<str[i]; j++){ 47 if(i==len && !j) continue; 48 if(abs(str[i+1]-j)<2 && i!=len)continue; 49 ret += dp[i][j]; 50 } 51 if(abs((str[i+1])-(str[i]))<2 && i!=len){ 52 flag = false; 53 break; 54 } 55 } 56 if(flag)ret++; 57 return ret; 58 } 59 60 int main() 61 { 62 // freopen("in.txt", "r", stdin); 63 ll a, b; 64 init(); 65 while(cin >> a >> b){ 66 ll ans = solve(b)-solve(a-1); 67 cout << ans << endl; 68 } 69 return 0; 70 }