P2657 [SCOI2009]windy数

Posted jcrl

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P2657 [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 。

#1:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
int n,m,f[20][10];
int print(int n)
{
    int ans=0,a[12]={0},l=0,x=n;
    while(x)
    {
        a[++l]=x%10;
        x/=10;
    }
    for(int i=1;i<=l-1;i++)
        for(int k=1;k<=9;k++)
        ans+=f[i][k];
    for(int k=1;k<a[l];k++)
        ans+=f[l][k];
    for    (int i=l-1;i>0;--i)
    {
        for(int j=1;j<=a[i];j++)
        {
            if(abs(j-a[i+1])>1) ans+=f[i][j];
        }
        if(abs(a[i]-a[i+1])>1)break;
    } 
    return ans;
}
int main()
{
    cin>>n>>m;    
    for(int i=0;i<=9;i++)
    f[1][i]=1;
    for(int i=2;i<=10;i++)
        for(int j=0;j<=9;j++)
            for(int k=0;k<=9;i++)
            if(abs(j-k)>1)        
            f[i][j]+=f[i-1][k];
        cout<<print(m)-print(n-1);
     
} 

40分代码(样例全过ToT):

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    using namespace std;
    int n,m,f[20][10],a[12];
    int print(int n)
    {
        memset(a,0,sizeof a);
        int ans=0,l=0,x=n;
        while(x)
        {
            a[++l]=x%10;
            x/=10;
        }
        for(int i=1;i<=l-1;i++)
            for(int k=1;k<=9;k++)
            ans+=f[i][k];
        for(int k=1;k<a[l];k++)
            ans+=f[l][k];
        for    (int i=l-1;i>0;--i)
        {
            for(int j=1;j<=a[i];j++)
            {
                if(abs(j-a[i+1])>1) ans+=f[i][j];
            }
            if(abs(a[i]-a[i+1])>1)break;
        } 
        return ans;
    }
    int main()
    {
        cin>>n>>m;    
        for(int i=0;i<=9;i++)
        f[1][i]=1;
        for(int i=2;i<=10;i++)
            for(int j=0;j<=9;j++)
                for(int k=0;k<=9;k++)
                if(abs(j-k)>1)        
                f[i][j]+=f[i-1][k];
            cout<<print(m)-print(n-1);
         
    } 

改了一个,变成20分了(ToT):

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    using namespace std;
    int n,m,f[20][10],a[12];
    int print(int n)
    {
        memset(a,0,sizeof a);
        int ans=0,l=0,x=n;
        while(x)
        {
            a[++l]=x%10;
            x/=10;
        }
        for(int i=1;i<=l-1;i++)
            for(int k=1;k<=9;k++)
            ans+=f[i][k];
        for(int k=1;k<a[l];k++)
            ans+=f[l][k];
        for    (int i=l-1;i>0;--i)
        {
            for(int j=0;j<=a[i];j++)
            {
                if(abs(j-a[i+1])>1) ans+=f[i][j];
            }
            if(abs(a[i]-a[i+1])>1)break;
        } 
        return ans;
    }
    int main()
    {
        cin>>n>>m;    
        for(int i=0;i<=9;i++)
        f[1][i]=1;
        for(int i=2;i<=10;i++)
            for(int j=0;j<=9;j++)
                for(int k=0;k<=9;k++)
                if(abs(j-k)>1)        
                f[i][j]+=f[i-1][k];
            cout<<print(m)-print(n-1);
         
    } 

,,,又改了一个点,然后20分,而且跟上个代码A的测试点不一样(ToT)

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    using namespace std;
    int n,m,f[20][10],a[12];
    int print(int n)
    {
        memset(a,0,sizeof a);
        int ans=0,l=0,x=n;
        while(x)
        {
            a[++l]=x%10;
            x/=10;
        }
        for(int i=1;i<=l-1;i++)
            for(int k=1;k<=9;k++)
            ans+=f[i][k];
        for(int k=1;k<a[l];k++)
            ans+=f[l][k];
        for    (int i=l-1;i>0;--i)
        {
            for(int j=0;j<=a[i]-1;j++)
            {
                if(abs(j-a[i+1])>1) ans+=f[i][j];
            }
            if(abs(a[i]-a[i+1])>1)break;
        } 
        return ans;
    }
    int main()
    {
        cin>>n>>m;    
        for(int i=0;i<=9;i++)
        f[1][i]=1;
        for(int i=2;i<=10;i++)
            for(int j=0;j<=9;j++)
                for(int k=0;k<=9;k++)
                if(abs(j-k)>1)        
                f[i][j]+=f[i-1][k];
            cout<<print(m)-print(n-1);
         
    } 

90分。。。

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    using namespace std;
    int n,m,f[20][10],a[12];
    int print(int n)
    {
        memset(a,0,sizeof a);
        int ans=0,l=0,x=n;
        while(x)
        {
            a[++l]=x%10;
            x/=10;
        }
        for(int i=1;i<=l-1;i++)
            for(int k=1;k<=9;k++)
            ans+=f[i][k];
        for(int k=1;k<a[l];k++)
            ans+=f[l][k];
        for    (int i=l-1;i>0;--i)
        {
            for(int j=0;j<=a[i]-1;j++)
            {
                if(abs(j-a[i+1])>1) ans+=f[i][j];
            }
            if(abs(a[i]-a[i+1])<=2)break;
        } 
        return ans;
    }
    int main()
    {
        cin>>n>>m;    
        for(int i=0;i<=9;i++)
        f[1][i]=1;
        for(int i=2;i<=10;i++)
            for(int j=0;j<=9;j++)
                for(int k=0;k<=9;k++)
                if(abs(j-k)>1)        
                f[i][j]+=f[i-1][k];
            cout<<print(m)-print(n-1);
         
    } 

终于A了。

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    using namespace std;
    int n,m,f[20][10],a[12];
    int print(int n)
    {
        memset(a,0,sizeof a);
        int ans=0,l=0,x=n;
        while(x)
        {
            a[++l]=x%10;
            x/=10;
        }
        for(int i=1;i<=l-1;i++)
            for(int k=1;k<=9;k++)
            ans+=f[i][k];
        for(int k=1;k<a[l];k++)
            ans+=f[l][k];
        for    (int i=l-1;i>0;--i)
        {
            for(int j=0;j<=a[i]-1;j++)
            {
                if(abs(j-a[i+1])>1) ans+=f[i][j];
            }
            if(abs(a[i]-a[i+1])<=2)break;
        } 
        return ans;
    }
    int main()
    {
        cin>>n>>m;    
        for(int i=0;i<=9;i++)
        f[1][i]=1;
        for(int i=2;i<=10;i++)
            for(int j=0;j<=9;j++)
                for(int k=0;k<=9;k++)
                if(abs(j-k)>1)        
                f[i][j]+=f[i-1][k];
            cout<<print(m+1)-print(n);
         
    } 

所以有前导0的也要加入DP

以上是关于P2657 [SCOI2009]windy数的主要内容,如果未能解决你的问题,请参考以下文章

P2657 [SCOI2009]windy数

luogu P2657 [SCOI2009]windy数 数位dp 记忆化搜索

P2657 [SCOI2009]windy数

P2657 [SCOI2009]windy数 题解

P2657 [SCOI2009] windy 数

P2657 [SCOI2009]windy数