• 2019暑假集训 windy数


    题目描述
    Windy 定义了一种 Windy 数:不含前导零且相邻两个数字之差至少为2的正整数被称为 Windy 数。

    Windy 想知道,在A和B之间,包括A和B,总共有多少个 Windy 数?
    输入
    一行两个数,分别为A,B。
    输出
    输出一个整数,表示答案。
    样例输入
    样例输入 1
    1 10
    
    样例输入 2
    25 50
    样例输出
    样例输出 1
    9
    
    样例输出 2
    20
    提示
    20%的数据,满足1<=A<=B<=1e6;
    100%的数据,满足1<=A<=B<=2e9。

    又是一道裸的数位dp,但是应当注意,为了区分前导0和中间0的区别,我们将前导0看作11,
    这样可以防止前导0后面不能放置1(因为差小于2),这样即可判断每一个0前面是否为前导0,若是,则该位为前导0
    上代码
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #define olinr return
    #define _ 0
    #define love_nmr 0;
    using namespace std;
    int digit[105],dp[105][105],idx,a,b;
    int DP(int pos,int statu,int limit)
    {
        if(!pos)return 1;
        if(!limit&&~dp[pos][statu])return dp[pos][statu];
        int res=0;
        int end=limit?digit[pos]:9;
        for(int i=0;i<=end;i++)
        {
            if(abs(statu-i)<2)continue;//差为2
            if(statu==11&&i==0)res+=DP(pos-1,11,limit&&i==end);//前导0
            else res+=DP(pos-1,i,limit&&i==end);
        }
        if(!limit)dp[pos][statu]=res;
        return res;
    }
    int solve(int num)
    {
        memset(dp,-1,sizeof dp);
        memset(digit,0,sizeof digit);
        idx=0;
        int temp=num;
        while(temp>0)
        {
            digit[++idx]=temp%10;
            temp/=10;
        }
        return DP(idx,11,1);
    }
    int main()
    {
        scanf("%d%d",&a,&b);
        printf("%d",solve(b)-solve(a-1));
        olinr ~~(0^_^0)*love_nmr
    }
    /*====年轻人,瞎搞是出不了省一的,这就是现实====*/
  • 相关阅读:
    计算机网络(1)----概述
    博客园自定义样式
    linux进程
    接口回调解析
    优先级队列
    双栈实现队列
    递归解决反转链表的一部分
    Multisim 之逻辑转换仪
    Multisim 如何添加文本 如何编辑文本字体
    Multisim 中的一些快捷键
  • 原文地址:https://www.cnblogs.com/qxds/p/11350512.html
Copyright © 2020-2023  润新知