uestc 250 windy数
windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,
在A和B之间,包括A和B,总共有多少个windy数?
Input
包含两个整数,A B。
Output
一个整数
Sample Input
【输入样例一】
1 10
【输入样例二】
25 50
Sample Output
【输出样例一】
9
【输出样例二】
20
Hint
【数据规模和约定】
100%的数据,满足 1 <= A <= B <= 2000000000 。
思路:按照数位dp模版,先确定一个dp数组, 这里用dp[i][j][k], i代表位数,j代表上一位,k 为0 表示前面的不是前导0,为 1 表示前面的是前导0
#include<cstdio>
#include<cstring>
using namespace std;
int dp[15][10][2]; //i 位数,j上一位,k是否前导0 0不是,1是
int a[15];
int ab(int x){
return x < 0 ? -x : x;
}
int dfs(int pos,int pre,bool sta, bool limit){
if(pos == -1) return 1;
if(!limit && dp[pos][pre][sta] != -1) return dp[pos][pre][sta];
int up = limit ? a[pos] : 9;
int ans = 0;
for(int i = 0;i <= up;i ++){
if(ab(i-pre) < 2 && !sta) continue; //如01(第一个0为前导0)这种情况,不continue,需要添加 一个判断前导0 的条件
ans += dfs(pos-1,i,sta && i == 0,limit && i == a[pos]);
}
if(!limit) dp[pos][pre][sta] = ans;
return ans;
}
int slove(int x){
int pos = 0;
while(x){
a[pos ++] = x % 10;
x /= 10;
}
return dfs(pos-1,0,true,true);
}
int main()
{
int a,b;
memset(dp,-1,sizeof(dp));
while(~scanf("%d%d",&a,&b)){
printf("%d\n",slove(b)-slove(a-1));
}
return 0;
}