Description
windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,在A和B之间,包括A和B,总共有多少个windy数?

Input
包含两个整数,A B

Output
一个整数

输入样例一
1 10

输入样例二
25 50

输出样例一
9

输出样例二
20

数据规模和约定
100%的数据,满足 1<=A<=B<=2000000000

Source

思路
数位dp,注意预处理和枚举时都要考虑|aiai1|>=2这个约束条件。

代码

#include <cstdio>
#include <cmath>
#include <algorithm>

const int maxn=13;

long long f[maxn+1][10];
long long t[maxn+1],a,b;

int init();

long long calc(long long n);

int main()
{
    init();
    scanf("%lld%lld",&a,&b);
    printf("%lld\n",calc(b)-calc(a-1));
    return 0;
}

int init()
{
    t[1]=1;
    for(int i=2; i<=13; i++)
    {
        t[i]=t[i-1]*10;
    }
    for(int i=0; i<=9; i++)
    {
        f[1][i]=1;
    }
    for(int i=2; i<=13; i++)
    {
        for(int j=0; j<=9; j++)
        {
            for(int k=0; k<=9; k++)
            {
                if(abs(j-k)>=2)
                {
                    f[i][k]+=f[i-1][j];
                }
            }
        }
    }
    return 0;
}

long long calc(long long n)
{
    long long res=0;
    if(!n)
    {
        return res;
    }
    int len=log(n)/log(10)+1;
    for(int i=1; i<len; i++)
    {
        for(int j=1; j<=9; j++)
        {
            res+=f[i][j];
        }
    }
    int h=n/t[len];
    n%=t[len];
    for(int i=1; i<h; i++)
    {
        res+=f[len][i];
    }
    int pre=h;
    for(int j=len-1; j>0; j--)
    {
        h=n/t[j];
        n%=t[j];
        for(int i=0; i<h; i++)
        {
            if(abs(pre-i)>=2)
            {
                res+=f[j][i];
            }
        }
        if(j==1)
        {
            if(abs(pre-h)>=2)
            {
                res+=f[1][h];
            }
        }
        if(abs(h-pre)<2)
        {
            break;
        }
        pre=h;
    }
    return res;
}