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;
    }
    

      

  • 相关阅读:
    如何理解 Dictionary Entity Type的作用 !
    Compiere去掉参考下的"显示翻译"
    Compiere去掉菜单中的"脚本""编辑器"
    Compiere去掉选择中的选择下的"用户界面设置""角色"两个按钮
    改变compiere界面
    Compiere a script to remove a client
    Compiere 制造模块
    Compiere去掉启动时的下面显示的进度条
    Compiere修改数据库连接对话窗的图像
    NHibernate Contrib Best Practice
  • 原文地址:https://www.cnblogs.com/something-for-nothing/p/7886183.html
Copyright © 2011-2022 走看看