zoukankan      html  css  js  c++  java
  • BZOJ 1026 Scoi2009 windy数

    1026: [SCOI2009]windy数

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 8765  Solved: 3957
    [Submit][Status][Discuss]

    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

    我觉得网上大部分的题解写的有点扯

    只用到了一小部分dp,其他的都是模拟

    首先dp预处理出来f[i][j]表示以最高位为j的i位数总共含有多少个windy数

    我们求n~m的windy数,也就是求1~m的windy数-1~n的windy数

    感觉没有实际的例子不是很好说代码是怎么运行的,举个例子吧

    比如说2596476

    首先1~1999999之间的所有windy数都是符合条件的

    2000000~2499999之间的windy数也都是符合条件的

    2500000~2589999之间的windy也都是符合条件的

    同理 

    2590000~2595999     2596000~2596399

    2596400~2596479     2596470~2596479

    这些区间中的windy数都是符合条件的

    我们依次去枚举这些区间,把答案累加到sum上

    具体数先看代码,最后把1~n中的windy数和1~m中的windy数相减即为答案

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0;int f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int f[20][15]={};
    string str1,str2;
    void init(){
       cin>>str1;cin>>str2;
    }
    void solve(){
        for(int i=0;i<=9;i++){
            f[1][i]=1;
        }
        for(int i=2;i<=15;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];
                }
            }
        }
        int str1l=str1.size();int str2l=str2.size();
        int sum1=0;int sum2=0;
        for(int i=1;i<str1l;i++){
            for(int j=1;j<=9;j++){
                sum1+=f[i][j];
            }
        }
        for(int i=1;i<str2l;i++){
            for(int j=1;j<=9;j++){
                sum2+=f[i][j];
            }
        }
        for(int i=1;i<str1[0]-'0';i++){
            sum1+=f[str1l][i];
        }
        for(int i=1;i<str2[0]-'0';i++){
            sum2+=f[str2l][i];
        }
        for(int i=0;i<str1l-1;i++){
            int tn=str1[i]-'0';
            int tnt=str1[i+1]-'0';
            for(int j=0;j<tnt;j++){
                if(abs(tn-j)>=2) sum1+=f[str1l-i-1][j];
            }
            if(abs(str1[i+1]-str1[i])<2) break;
        }
        for(int i=0;i<str2l;i++){
            int tn=str2[i]-'0';
            int tnt=str2[i+1]-'0';
            for(int j=0;j<tnt;j++){
                if(abs(tn-j)>=2) sum2+=f[str2l-i-1][j];
            }
            if(abs(str2[i+1]-str2[i])<2) break;
            if(i==str2l-2) sum2++;
        }
        cout<<sum2-sum1<<endl;
    }
    int main(){
        //freopen("All.in","r",stdin);
        //freopen("zhang.out","w",stdout);
        init();
        solve();
        return 0;
    }
    

    对拍代码

    #include <bits/stdc++.h>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0;int f=1;char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
        while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    int main(){
        freopen("All.in","w",stdout);
        srand(int(time(NULL)));
        int n=rand()%100007+1;int m=rand()%100007+1;
        if(n>m) swap(n,m);
        cout<<n<<' '<<m<<endl;
        return 0;
    }
    

      

  • 相关阅读:
    Netty与Spring Boot的整合
    Activiti 5.22.0 之自由驳回任务实现(亲测)
    学习机器学习前你应该要知道的一些事
    机器学习中调参的基本思想
    机器学习和深度学习区别的简要概述
    SKlearn中分类决策树的重要参数详解
    世界第二大软件国家如何看待人工智能、机器学习和大数据
    sklearn中的数据预处理和特征工程
    人工智能革命:人类永生还是灭亡(下)
    人工智能革命:人类永生还是灭亡(中)
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/7886183.html
Copyright © 2011-2022 走看看