题目描述
原题来自:SCOI 2009
Windy 定义了一种 Windy 数:不含前导零且相邻两个数字之差至少为2的正整数被称为 Windy 数。
Windy 想知道,在A和B之间,包括A和B,总共有多少个 Windy 数?
输入格式
一行两个数,分别为A,B。
输出格式
输出一个整数,表示答案。
样例
样例输入 1
1 10
样例输出 1
9
样例输入 2
25 50
样例输出 2
20
数据范围与提示
20%的数据,满足1≤A≤B≤10^6 ;
100%的数据,满足 1≤A≤B≤2*10^9 。
代码:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=110;
long long po[N];
int f[N][N],ans,a,b;
void pre() {
po[0]= 1;
for (int i=1; i<=12; i++)
po[i]=po[i-1]*10;
for (int i=0; i<=9; i++)
f[1][i]=1;
for (int i=2; i<=11; 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 work(int x) {
int w=0, ans=0;
while(po[w]<=x)
w++;
for(int i=1; i<w; i++)
for (int j=1; j<=9; j++)
ans+=f[i][j];
int y=x/po[w-1];
for(int i=1; i<y; i++)
ans+=f[w][i];
int now=y;
x%=po[w-1];
for(int i=w-1; i>=1; i--) {
y=x/po[i-1];
for(int j=0; j<y; j++)
if (abs(j-now)>=2)
ans+=f[i][j];
if(abs(now-y)<2)
break;
now=y;
x%=po[i-1];
}
return ans;
}
int main() {
scanf("%d%d",&a,&b);
pre();
printf("%d\n",work(b+1)-work(a));
return 0;
}