zoukankan      html  css  js  c++  java
  • [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 。

    dp[i][j]:表示共有i位,其中最高位为j满足条件的方案数。

    其中定义j=10为前导零不受限制。

    则按照数位dp板子。

    分3种情况。

    第一种情况:当前位-上一位大于等于2 比如 47xxxxx,则需要从0,累加到2,再从6累加到6.

    第二种情况,上一位比当前为大等于2 比如74xxxxx 则从0循环到4-1

    第三种情况 abs(上一位-当前位)小于2 如 45

    则从0循环到4-2,然后直接break掉。因为5的时候不满足条件。

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll dp[15][15];
    void init()
    {
        for(int i=0;i<=9;++i)
        {
            dp[1][i]=1;
        }
        for(int i=2;i<=12;++i)
        {
            for(int j=0;j<=10;++j)
            {
                if(j!=10)
                {
                    for(int k=j+2;k<=9;++k)
                    {
                        dp[i][j]+=dp[i-1][k];
                    }
                    for(int k=j-2;k>=0;--k)
                    {
                        dp[i][j]+=dp[i-1][k];
                    }
                }
                else
                {
                    for(int k=1;k<=10;++k)
                    {
                        dp[i][j]+=dp[i-1][k];
                    }
                }
            }
        }
    }
    ll a[15];
    ll count(ll x)
    {
        memset(a,0, sizeof(a));
        int cnt=0;
        while(x>0)
        {
            a[++cnt]=x%10;
            x/=10;
        }
        ll res=0;
        for(ll i=a[cnt]-1;i>=1;--i)
        {
            res+=dp[cnt][i];
        }
        res+=dp[cnt][10];
        for(int i=cnt-1;i>=1;--i)
        {
            if(abs(a[i+1]-a[i])<2)
            {
                for(int j=0;j<=a[i+1]-2;++j)
                {
                    res+=dp[i][j];
                }
                break;
            }
            else if(a[i]-a[i+1]>=2)
            {
                for(ll j=a[i]-1;j>=a[i+1]+2;j--)
                {
                    res+=dp[i][j];
                }
                for(int j=0;j<=a[i+1]-2;++j)
                {
                    res+=dp[i][j];
                }
            }
            else if(a[i+1]-a[i]>=2)
            {
                for(ll j=a[i]-1;j>=0;--j)
                {
                    res+=dp[i][j];
                }
            }
        }
        return res;
    }
    int main()
    {
        init();
        ll x,y;
        //cout<<count(5143)<<endl;
        scanf("%lld%lld",&x,&y);
        printf("%lld
    ",count(y+1)-count(x));
        return 0;
    }
    

      

  • 相关阅读:
    Autofac ASP.NET Web API (Beta) Integration
    An Autofac Lifetime Primer
    Web api help page error CS0012: Type "System.Collections.Generic.Dictionary'2错误
    c++ 全局变量初始化的一点总结
    C++中extern关键字用法小结
    为什么多线程读写 shared_ptr 要加锁?
    CentOS7 安装Chrome
    在CentOS 7中使用VS Code编译调试C++项目
    am335x hid-multitouch.c
    implicit declaration of function 'copy_from_user'
  • 原文地址:https://www.cnblogs.com/zyf3855923/p/10353675.html
Copyright © 2011-2022 走看看