洛谷-2657 [SCOI2009]windy数

核能气质少年 提交于 2019-12-02 11:19:50

题目描述
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 。

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

#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;
}


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!