洛谷-2657 [SCOI2009]windy数

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

输入输出样例
输入 #1
1 10

输出 #1
9

输入 #2
25 50

输出 #2
20

说明/提示
100%的数据,满足 1 <= A <= B <= 2000000000 。

解释:数位 d p dp dp, d p [ i ] [ j ] : i dp[i][j]:i dp[i][j]i位,以 j j j为开头满足条件的数, d p [ i ] [ j ] + = d p [ j − 1 ] [ k ] , a b s ( k − j ) > = 2 dp[i][j]+=dp[j-1][k],abs(k-j)>=2 dp[i][j]+=dp[j1][k],abs(kj)>=2,就是以0开头的话我们需要特殊处理一下,如果以0开头,则无 a b s ( k − j ) > = 2 abs(k-j)>=2 abs(kj)>=2条件,并且把它保存在 t e te te数组里面

#include<iostream>
#include<algorithm>
using namespace std;
long long dp[14][13]={0};
long long te[14]={0};
long long Abs(long long x){
    if(x>0) return x;
    return -x;
}
long long ok(long long n){
    long long a[14]={0};
    long long len=0;
    long long m=n;
    while(m){
        a[++len]=m%10;m/=10;
    }
    long long ret=te[len];
    reverse(a+1,a+1+len);
    for(long long i=1;i<=len;i++){
        for(long long j=((i==1)?1:0);j<a[i];j++){
            if(Abs(a[i-1]-j)>=2||i==1) ret+=dp[len-i+1][j];
        }
        if(Abs(a[i]-a[i-1])<2&&i!=1) break;
    }
    long long i=0;
    if(len>=2)
        for(i=2;i<=len;i++){
            if(Abs(a[i]-a[i-1])<2) break;
        }
    if(i>len) ret++;
    return ret;
}
int main(){
    for(long long i=0;i<10;i++) dp[1][i]=1LL;
    te[1]=0;
    te[0]=0;
    for(long long i=2;i<14;i++){
        for(long long j=0;j<10;j++){
            for(long long k=0;k<10;k++){
                if(Abs(k-j)>=2) dp[i][j]+=dp[i-1][k];
            }
            if(j) te[i]+=dp[i-1][j];
        }
        te[i]+=te[i-1];
    }
    long long l,r;cin>>l>>r;
    cout<<ok(r)-ok(l-1)<<endl;
    return 0;
}


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值