[SCOI2009] windy 数
题目背景
windy 定义了一种 windy 数。
题目描述
不含前导零且相邻两个数字之差至少为 2 2 2 的正整数被称为 windy 数。windy 想知道,在 a a a 和 b b b 之间,包括 a a a 和 b b b ,总共有多少个 windy 数?
输入格式
输入只有一行两个整数,分别表示 a a a 和 b b b。
输出格式
输出一行一个整数表示答案。
样例 #1
样例输入 #1
1 10
样例输出 #1
9
样例 #2
样例输入 #2
25 50
样例输出 #2
20
提示
数据规模与约定
对于全部的测试点,保证
1
≤
a
≤
b
≤
2
×
1
0
9
1 \leq a \leq b \leq 2 \times 10^9
1≤a≤b≤2×109。
dp做法
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a,b;
ll f[36][10];//代表i个数字下以j开头的方案个数
void init(){
for(int i=0;i<=9;i++) f[1][i]=1;
for(int i=2;i<=36;i++){
for(int j=0;j<=9;j++){
for(int k=0;k<=9;k++){
if(abs(j-k)>=2) f[i][j]+=f[i-1][k];
}
}
}
}
int dp(int x){
if(!x) return 0;
ll ans=0;
int last=-2,t;
vector<int> num;
while(x){
num.push_back(x%10);x/=10;
}
for(int i=num.size()-1;i>=0;i--){
t=num[i];
for(int j=(i==num.size()-1);j<t;j++){
if(abs(last-j)>=2){
ans+=f[i+1][j];
}
}
if(abs(last-t)<2) break;
last=t;
if(!i) ans++;
}
for(int i=1;i<num.size();i++){
for(int j=1;j<=9;j++){
ans+=f[i][j];
}
}//这里为什么要特判呢,是因为我们在进行上面的循环计数时候,自动把包含前导零的比如00135这样的数字给漏掉了,所以这个循环要把这些数加上
return ans;
}
int main(){
init();
cin>>a>>b;
cout<<dp(b)-dp(a-1);
}