一本通1587例 3Windy 数

Posted gaojunonly1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一本通1587例 3Windy 数相关的知识,希望对你有一定的参考价值。

1587: 【例 3】Windy 数

时间限制: 1000 ms         内存限制: 524288 KB

题目描述

原题来自:SCOI 2009

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

Windy 想知道,在 A 和 B 之间,包括 A 和 B,总共有多少个 Windy 数?

输入格式

一行两个数,分别为 A,B。

输出格式

输出一个整数,表示答案。

样例

样例输入 1

1 10

样例输出 1

9

样例输入 2

25 50

样例输出 2

20

数据范围与提示

20% 的数据,满足 1AB10^6;
100% 的数据,满足 1AB2×10^9。

 

sol:windy数,也是很友好的数位dp,也像数字游戏一样搞一搞,dp[i][j][Bo1][Bo2]第i位,填的数字为j,是否是上界,是否是前导0就over了

技术图片
#include <bits/stdc++.h>
using namespace std;
int Num[20],dp[20][10][2][2];
inline int dfs(int Weiz,int Shuz,bool Shangj,bool Qiand0)
{
    if(dp[Weiz][Shuz][Shangj][Qiand0]) return dp[Weiz][Shuz][Shangj][Qiand0];
    if(Weiz==1) return (dp[Weiz][Shuz][Shangj][Qiand0]=1);
    int i,Up=(Shangj)?(Num[Weiz-1]):(9);
//    printf("Up=%d
",Up);
    for(i=0;i<=Up;i++) if((Qiand0)||(abs(Shuz-i)>1))
    {
        bool Bo1=(Shangj&&i==Up),Bo2=(Qiand0&&i==0);
        dp[Weiz][Shuz][Shangj][Qiand0]+=dfs(Weiz-1,i,Bo1,Bo2);
    }
    return dp[Weiz][Shuz][Shangj][Qiand0];
}
inline int Solve(int n)
{
    if(n==0) return 1;
    memset(dp,0,sizeof dp);
    *Num=0;
    while(n)
    {
        Num[++*Num]=n%10;
        n/=10;
    }
    int i,ans=0;
    ans+=dfs(*Num,0,0,1);
//    printf("Beg ans=%d
",ans);
    for(i=1;i<Num[*Num];i++)
    {
        ans+=dfs(*Num,i,0,0);
    }
    ans+=dfs(*Num,Num[*Num],1,0);
    return ans;
}
int main()
{
    int l,r;
    scanf("%d%d",&l,&r);
    printf("%d
",Solve(r)-Solve(l-1));
    return 0;
}
/*
input
1 10
output
9

input
25 50
output
20
*/
View Code

 


以上是关于一本通1587例 3Windy 数的主要内容,如果未能解决你的问题,请参考以下文章

loj10165. 「一本通 5.3 例 3」Windy 数

一本通1586 例 2数字游戏

题解一本通1553:例 2暗的连锁

noip信息学一本通1332:例2-1周末舞会

算法?日更?第十七期信息奥赛一本通1598: 例 2最大连续和题解

10249「一本通 1.3 例 5」weight