[SCOI2009]windy数

时间:2019-09-25
本文章向大家介绍[SCOI2009]windy数,主要包括[SCOI2009]windy数使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

洛咕

题意:给定数对\(l,r\),求\([l,r]\)内不含前导零且相邻两个数字之差至少为2的正整数的个数.\(1<=l<=r<= 2000000000.\)

直接套模板就好了.因为题目保证了\(l>=1\)所以可以不特判.

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<set>
#define ll long long
using namespace std;
inline int read(){
    int x=0,o=1;char ch=getchar();
    while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
    if(ch=='-')o=-1,ch=getchar();
    while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    return x*o;
}
int len,a[15],dp[15][10];
inline int dfs(int pos,int pre,int lead,int limit){
    if(pos>len)return 1;//找到了一个合法的数
    if(dp[pos][pre]!=-1&&(!lead)&&(!limit))return dp[pos][pre];//记忆化搜索
    int cnt=0,res=limit?a[len-pos+1]:9;
    for(int i=0;i<=res;++i){//枚举当前pos位能填的数
         if((!i)&&lead)cnt+=dfs(pos+1,0,1,limit&&(i==res));//处理前导零
         else if(i&&lead)cnt+=dfs(pos+1,i,0,limit&&(i==res));
         else if(abs(i-pre)>=2)cnt+=dfs(pos+1,i,0,limit&&(i==res));//相邻两位数的差的绝对值要大于等于2
    }
    return (!limit&&!lead)?dp[pos][pre]=cnt:cnt;
}
inline int part(int x){
    len=0;
    while(x)a[++len]=x%10,x/=10;
    memset(dp,-1,sizeof(dp));
    dfs(1,0,1,1);
}
int main(){
    int l=read(),r=read();
    printf("%d\n",part(r)-part(l-1));
    return 0;
}

原文地址:https://www.cnblogs.com/PPXppx/p/11584270.html