zoukankan      html  css  js  c++  java
  • 牛客CSP2020赛前模拟赛-第一天

    得分100

    题目解析

    第一题

    题目描述:

    牛牛在注册不同的网站时,总是会使用不同的密码来保证他的账号安全。
    为了保证他的密码强度,牛牛使用他的“字符串筛选器”来测试密码的强度。
    具体来说,他先将输入的字符串筛选分成四部分。

    第一部分仅由小写英文字母组成

    第二部分仅由大写英文字母组成

    第三部分仅由0到9的数字组成

    第四部分由其余特殊字符组成

    这四部分要保留它们在原字符串中的相对顺序。

    比如将"1q2w3E4R5{6}"这个字符串进行筛选后

    四部分分别为:"qw"、"ER"、"123456"、"{}"。

    然后只要某一部分不为空,牛牛就认为他的密码等级高1级。
    密码等级最低为1级,最高4级。
    例如"asdA@123"的密码等级为4,"20020101"的密码等级为1。

    请帮助牛牛判断他注册账号时的密码等级,以及该密码做字符串筛选后的结果。

    解题思路:考察语言,直接模拟即可。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    string x[4], s;
    int ans;
    int main(){
        cin >> s;
        int len = s.length();
        for(int i = 0; i < len; i ++){
            if(s[i] <= 'z' && s[i] >= 'a'){
                x[0] += s[i];
                continue;
            }
            if(s[i] <= 'Z' && s[i] >= 'A'){
                 x[1] += s[i];
                continue;
            }
            if(s[i] <= '9' && s[i] >= '0'){
                x[2] += s[i];
                continue;
            }
            x[3] += s[i];
        }
        for(int i = 0 ; i < 4; i ++){
            if(x[i].size()) ans ++;
            else x[i] = "(Null)";
        }
        printf("password level:%d
    ", ans);
        for(int i = 0 ; i < 4; i ++){
            cout << x[i] << endl;
        }
        return 0;
    }
    

    第二题

    题目链接

    解题思路:

    这道题是个贪心,考试的时候想用搜索来做(枚举每个点,然后向前和向后搜),结果写挂了。
    看了题解,发现往回走是一个迷惑选项,只要一直往前(往右,即1 --> n + 1的方向)走就行了
    在向右走的过程中更新一个能走到的最远的点的编号,和最近的能到达最远的点的编号(因为要维护字典序),如果当前走到的点就是最远能到达的点,说明不论怎样走都无法在往前,就是用魔法,使用魔法的点的编号就是最近的能到达最远的点的编号。如果最远能到达的点大于n,说明可以走到,结束输出就可以了。
    这块有点绕,看代码就清楚了。

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5+10;
    int n,num,minpos=1,maxdis=1,a[N],ans[N];
    /*
    num表示施展法术的数目;
    minpos表示(两段施展法术之间区间的位置中)离最远能达到点最远的位置,即上述i位置;
    maxdis表示(施展下一次法术之前)能达到的最远距离,即上述绿色位置;
    ans[i]表示第i次施展法术的位置。
    */
    int main(){
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        for(int i=1;i<=n;i++){
            if(a[i]){
                if(i+a[i]>maxdis){//如果能跳到的最远距离比记录的maxdis大
                    maxdis=i+a[i];//刷新
                    minpos=i;//记录下来能跳到最远距离对应的第一个位置,就是最靠左的位置
                }
            }
            else if(maxdis==i){//前面区间的位置最远也就到i(此i非上述i,而是循环遍历到的i)了,必须施展法术了
                ans[++num]=minpos;//把记录的最靠前的能一次到达最远距离的位置,加入答案中
                maxdis=i+1;//更新最远能到达的位置为i+1
                minpos=i+1;//更新最靠前能到达maxdis的位置为i+1
                //上面两步可以理解为“又回到最初的起点,记忆中你青涩的脸……”,就相当于又开辟了一段区间,而这段区间的左端点正是你上次施展法术后刚好到达的位置。略讲在另附中。
            }
            if(maxdis>n) break;
        }
        cout<<num<<endl;
        for(int i=1;i<=num;i++) cout<<ans[i]<<' ';
    }
    

    这个是题解的代码。
    题解写的比我写的清楚:链接

    第三题

    目测是个并查集,考试的时候一直在写第二题,没来得及看。
    正在研究,持续更新......

  • 相关阅读:
    Greedy Gift Givers 贪婪的送礼者
    USACO 1.1.3 Friday the Thirteenth 黑色星期五
    Prime Matrix(暴力出奇迹)
    博弈论
    好车牌
    C语言中动态内存的分配(malloc,realloc)
    Saruman's Army(贪心)
    Python练习——循环2
    Fox and Number Game
    Repair the Wall (贪心)
  • 原文地址:https://www.cnblogs.com/sjzez-llb/p/13836807.html
Copyright © 2011-2022 走看看