zoukankan      html  css  js  c++  java
  • BZOJ1026: [SCOI2009]windy数

    Time Limit: 1 Sec  Memory Limit: 162 MB

    Description

      windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,
    在A和B之间,包括A和B,总共有多少个windy数?

    Input

      包含两个整数,A B。

    Output

      一个整数

    Sample Input

    【输入样例一】
    1 10
    【输入样例二】
    25 50

    Sample Output

    【输出样例一】
    9
    【输出样例二】
    20

    HINT

    【数据规模和约定】

    100%的数据,满足 1 <= A <= B <= 2000000000 。

    Source

    递推方程很好想,用f[i][j]表示i位数第i位为j的数的个数

    对于一个数想求比它小的有多少个windy数,用752举例

    首先求1~699

    接着700~749

    最后750~752另一件事,为什么要记录并递推f[i][0],并且把f[1][0]标记为1

    对于702的递推如果不递推f[2][0]就无法统计。

    对于20如果不把f[1][0]标记为1也无法统计。

    而且由于求的是一段区间,所以答案不会改变。

    #include<cstdio>
    typedef long long ll;
    ll f[11][10];
    int cf[11];
    int jdz(int a)
    {
        return a>0?a:-a;
    }
    ll cnt(ll a)
    {
        int len=1;
        ll re=0;
        for(;a;len++,a/=10) cf[len]=a%10;
        for(int i=2;i<len;i++) re+=f[i-1][0]+f[i-1][1];//对于最高位0的其实并不需要保证第i-1不为1,0.所以这一部分会少统计
        for(int sg=-2,ssg=-10,i=len-1;i;i--)
        {
            for(int j=cf[i]-1;j>=0;j--)
                if(sg-j>1||j-sg>1) re+=f[i][j];
            if(sg<0) sg=cf[i];
            else ssg=sg,sg=cf[i];
            if(jdz(ssg-sg)<2) break;
        }
        return re;
    }
    int main()
    {
        ll l,r;
        scanf("%lld%lld",&l,&r);
        for(int i=0;i<10;i++) f[1][i]=1;
        for(int i=2;i<=10;i++)
            for(int j=0;j<10;j++)
                for(int k=0;k<10;k++)
                    if(j-k>1||k-j>1) f[i][j]+=f[i-1][k];
        printf("%lld
    ",cnt(r+1)-cnt(l));
        return 0;
    }
  • 相关阅读:
    关于生成二维码的相关参考资料
    C#生成二维码的方法
    .NET 二维码生成(ThoughtWorks.QRCode)
    微信扫描二维码登录网站技术原理
    C# ArrayList的用法
    C#多线程编程
    c#使用多线程的几种方式示例详解
    解决Winform应用程序中窗体背景闪烁的问题
    C# 线程调用主线程中的控件
    30、网络编程
  • 原文地址:https://www.cnblogs.com/bzmd/p/6264890.html
Copyright © 2011-2022 走看看