• 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
    }
    /*====年轻人,瞎搞是出不了省一的,这就是现实====*/
  • 相关阅读:
    10 大排序算法总结
    什么是堆和栈
    8张思维导图学习javascript
    Service Locator 模式
    Unity系列文章
    IoC模式(依赖、依赖倒置、依赖注入、控制反转)
    ASP.NET应用程序与页面生命周期
    TCP/IP网络协议的通俗理解,SOCKET,HTTP,SOAP
    部分计算机上视频不能自动刷新的解决方案
    数梦工场Java实习面试(offer到手含面试经验及答案)
  • 原文地址:https://www.cnblogs.com/qxds/p/11350512.html
Copyright © 2020-2023  润新知