[SCOI2009]windy数

本人水平有限,题解不到为处,请多多谅解

 本蒟蒻谢谢大家观看

传送门:

https://www.luogu.org/problem/P2657

题意有点恶心:是说某一个数,其每一位上的相邻的数字之差大于或等于2

       

    和第一题lucky一样
    设个f[i][j] : f[i][j]表示取i位的首位数字是j
    转移就if(abs(j-k)>=2) f[i][j]+=f[i-1][k]; 
初值就个位数都是windy数

    此题仍然需要用前缀和 即:sum(b+1)-sum(a) ;

    预处理:f[1][i]=1因为个位数都满足题意

如果不明白转移可看我的第一题【NOIP 模拟题】lucky

博客:https://www.cnblogs.com/nlyzl/p/11262311.html

code:

#include<bits/stdc++.h>
using namespace std;
long long a,b;
int n,m,t;
int sum[100010];
int f[1001][1001];
int put(int x)
{
    memset(sum,0,sizeof(sum));
    int tl=x,tot=0,ans=0;
    while(tl)
    {
        sum[++tot]=tl%10;
        tl/=10;
    }
    for(int i=1;i<tot;i++)
        for(int j=1;j<=9;j++)
            ans+=f[i][j];
    for(int i=1;i<sum[tot];i++)
        ans+=f[tot][i];
    for(int i=tot-1;i;i--)
    {
        for(int j=0;j<sum[i];j++)
            if(abs(j-sum[i+1])>=2)
                ans+=f[i][j];
        if(abs(sum[i]-sum[i+1])<2)
            break;
    }
    return ans;
}
int main()
{
    scanf("%lld%lld",&a,&b);
    t=b;
    while(t)
    {
        m++;
        t/=10;
    }
    for(int i=0;i<=9;i++)
        f[1][i]=1;
    for(int i=1;i<=m;i++)
        for(int j=0;j<=9;j++)
            for(int k=0;k<=9;k++)
                if(abs(j-k)>=2)
                    f[i][j]+=f[i-1][k];
    printf("%d
",put(b+1)-put(a));
    return 0;
}
原文地址:https://www.cnblogs.com/nlyzl/p/11263793.html