zoukankan      html  css  js  c++  java
  • 2020-06-01 — 习题训练四题解

    https://vjudge.net/contest/376443#overview

    A-Dreamoon and Ranking Collection

    给x个补丁,从第一个开始补, 遇见漏洞,补丁就少一个, 补完之后,从一到最大的没毛病的数是多少

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    
    const int N = 2e5 + 10;
    
    template <typename T>
    
    inline void read(T &ret) {
        char c;
        int sgn;
        if (c = getchar(), c == EOF) return ;
        while (c != '-' && (c < '0' || c > '9')) c = getchar();
        sgn = (c == '-') ? -1:1;
        ret = (c == '-') ? 0:(c - '0');
        while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
        ret *= sgn;
        return ;
    }
    void solve(){
            
        int n, x, v;
        read(n), read(x);
        vector<int> a(n+1);
        vector<bool> s(300);
        
        for(int i = 1;i <= n; ++ i){
            read(a[i]);
            s[a[i]] = true;
        }
        for(int i = 1;i <= 300; ++ i){
            if(!s[i] && x > 0){
                x --;
                continue;
            }
            if(!s[i] && !x){
                v = i - 1;
                break;
            }
        }
        printf("%d
    ", v);
    }
    int main()
    {
        ios_base::sync_with_stdio(false);
        int t;
        read(t);
        while(t--) solve();
    }

    B - Dreamoon Likes Permutations

    给一个序列,切开,使得切开后的两个序列中的数字为从1到该序列的长度(数字不能重复),求所有满足题意的切法 

    用一个数组标记前面满足条件的序列,另一个标记后面满足条件的序列,最后输出。(借鉴某大佬)

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    
    const int N = 2e5 + 10;
    
    template <typename T>
    
    inline void read(T &ret) {
        char c;
        int sgn;
        if (c = getchar(), c == EOF) return ;
        while (c != '-' && (c < '0' || c > '9')) c = getchar();
        sgn = (c == '-') ? -1:1;
        ret = (c == '-') ? 0:(c - '0');
        while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
        ret *= sgn;
        return ;
    }
    void solve(){
            
                
        int n, cnt = 0;
        read(n);
    //    int a[n+1], cntl[n+1], cntr[n+1];
    //    bool l[n+1], r[n+1];    
        vector<int> a(n+1), cntl(n+1), cntr(n+1);
        vector<bool> l(n+1), r(n+1);
        for(int i = 1;i <= n; ++ i) 
            read(a[i]);
        int x = 1;
        for(int i = 1;i <= n; ++ i){
            cntl[a[i]] ++;
            if(cntl[a[i]] >= 2) break;
            
            while(cntl[x] == 1 && x <= i) x ++; // 若是到不了i ,从x 到i 之间有0,也就不合适.
            if(x - 1 == i)
             l[i] = true;  
        }
        x = 1;
        for(int i = n;i >= 1; -- i){
            cntr[a[i]] ++;
            if(cntr[a[i]] >= 2) break;
            
            while(cntr[x] == 1 && x <= n - i + 1) x ++;
            if(x - 1 == n - i + 1) r[i] = true;
        }
        
        for(int i = 1;i <= n-1; ++ i)
            if(l[i] && r[i+1]) cnt ++;
        printf("%d
    ", cnt);
        if(cnt)
        for(int i = 1;i < n; ++ i)
            if(l[i] && r[i + 1])
                printf("%d %d
    ", i, n - i);
        
    }    
    
    int main()
    {
        ios_base::sync_with_stdio(false);
        int t;
        read(t);
        while(t--) solve();
    }

    C - Exercising Walk

    大概分类讨论吧

    #include<iostream>
    using namespace std;
    int t, a, b, c, d, x, y, xl, xr, yl,yr;
    
    int main()
    {
        cin >> t;
        while (t--)
        {
            int flag = 0;
            cin >> a >> b >> c >> d;
            cin >> x >> y >> xl >> yl >> xr >> yr;
            //特判两种特殊情况
            if (xl == xr && (a >= 1 || b >= 1))
                flag = 0;
            else if(yl == yr && (c >= 1 || d >= 1))
                flag = 0;
            //判断是否在边界内
            else
            {
                x = x + (b - a);
                y = y + (d - c);
                if (x >= xl && x <= xr && y >= yl && y <= yr)
                flag = 1;
            }
            if (flag)
                cout << "YES" << endl;
            else 
                cout << "NO" << endl;
        }
        return 0;
    }

    D-Composite Coloring

     题意:给定n个合数,用m(<= 11) 种颜色染色,当两个数字有相同的公约数时可以染同一种颜色

    找出前11个质数,若公约数相同,染同样颜色,不同就换颜色。题目给出 m<= 11 即可。而a < 1000, 所以不会 出现  37 * 43 这样的数, 也就是说,前11个质数够用(第十一个质数为31) (借鉴某大佬)

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    
    const int N = 2e5 + 10;
    
    template <typename T>
    
    inline void read(T &ret) {
        char c;
        int sgn;
        if (c = getchar(), c == EOF) return ;
        while (c != '-' && (c < '0' || c > '9')) c = getchar();
        sgn = (c == '-') ? -1:1;
        ret = (c == '-') ? 0:(c - '0');
        while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
        ret *= sgn;
        return ;
    }
    int gcd(int a, int b)
    {
        while(b != 0)
        {
            int r = b;
            b = a % b;
            a = r;
        }
        return a;
    }
    void solve(){
            
        int prime[11] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31};
        int n, cnt = 0;
        read(n);
        vector<int> a(n+1), ans(n+1);
        map<int, int> dis;
        for(int i = 1;i <= n; ++ i) read(a[i]);
        
        for(int i = 1;i <= n; ++ i){
            for(int j = 0;j < 11; ++ j){
                if(a[i] % prime[j] == 0){
                    if(!dis[prime[j]]) dis[prime[j]] = ++ cnt;
                    ans[i] = dis[prime[j]];
                    break;
                }
            }
        }
        printf("%d
    ", cnt);
        for(int i = 1;i <= n; ++ i)
            printf("%d ",ans[i]);
        puts("");
    }
    int main()
    {
        ios_base::sync_with_stdio(false);
        int t;
        read(t);
        while(t--) solve();
    }

    E - K-th Beautiful String

    给出字符串aaaaaaaabb (类似) , 经过排列变换后,找出第 k 大的字符串(字典序)

    n - 2  个a:  a a a a ... a a a   , 两个b 插进去;

    第一个b 的位置 b = n - 1  :  a a a a ..... a a a b           k的可能取值为 1;

       b 的位置 b = n - 2  :  a a a a ..... a a b a          k :                      2  3 // 与不同的k 对应的另一个 b的位置应该能直接看出来

            b = n - 3      :a a a a ..... a b a a           k:                      4 5 6 

              。            k :         7 8 9 10

              。            

              。         

       b = 0         :   b a a a  .... a a a a             k :         i * ( i - 1) / 2 + 1    ....... ; (就当 i 从 1 开始自增好了)

    现在可以回答第k 个是哪个了, 首先找到 k 所在的行,就可以找到第一个b的位置了,然后用 k 减去 所在行的第一个数,就是另一个b与n-1的距离,两个b的位置就找到了

    //好麻烦,附个简洁的题解

    https://blog.csdn.net/mrcrack/article/details/105133833?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.nonecase

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    
    const int N = 2e5 + 10;
    
    template <typename T>
    
    inline void read(T &ret) {
        char c;
        int sgn;
        if (c = getchar(), c == EOF) return ;
        while (c != '-' && (c < '0' || c > '9')) c = getchar();
        sgn = (c == '-') ? -1:1;
        ret = (c == '-') ? 0:(c - '0');
        while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
        ret *= sgn;
        return ;
    }void solve(){
            
        int n, x;
        read(n), read(x);
        vector<char> a(n+1);
        for(int i = 1;i <= n - 2; ++ i) a[i] = 'a';
        int b1, b2;
        for(int i = 1;i <= n; ++ i){
            if((ll)i *(i - 1) / 2 + 1 > x){
                b1 = i-1;
                b1 = n - 1 - b1;
                b2 = x - ((ll) (i-1) * (i - 2) / 2 + 1);
                b2 = n - 2 - b2;
                break;
            }
        }
        for(int i = 0;i <= n-2; ++ i){
            if(i)
            putchar(a[i]);
            if(b1 == i) putchar('b');
            if(b2 == i) putchar('b');
        }
        puts("");        
    }
    int main()
    {
        ios_base::sync_with_stdio(false);
        int t;
        read(t);
        while(t--) solve();
    }

     F - Carousel

    题意: 闭合圈中,相邻的不同元素要涂成不同颜色,问最多需要多少种颜色可涂满,并写出涂法

    闭合圈中,有一种元素时,全输出1

    有两种元素时,循环输出1, 2;
    有三种元素时, 如果 n 为偶数, 循环输出1, 2;

           如果n 为奇数, 查找有无相邻相等的元素(闭合圈),如果有那就可以看成偶数列,第一次相等时, 相等的两个元素输出一样的数,这样就又可以看成偶数列了;

                                      如果没有相邻相等的,那就循环输出1, 2最后一个元素输出3

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    
    const int N = 2e5 + 10;
    
    template <typename T>
    
    inline void read(T &ret) {
        char c;
        int sgn;
        if (c = getchar(), c == EOF) return ;
        while (c != '-' && (c < '0' || c > '9')) c = getchar();
        sgn = (c == '-') ? -1:1;
        ret = (c == '-') ? 0:(c - '0');
        while (c = getchar(), c >= '0' && c <= '9') ret = ret * 10 + (c - '0');
        ret *= sgn;
        return ;
    }
    void solve(){
        
        int n, flag = 0;
        read(n);
        vector<int> a(n+1), ans(n+1);
        set<int> st;
        for(int i = 1;i <= n; ++ i){
            read(a[i]);
            if(i > 1 && a[i] == a[i-1])
                flag ++;
            if(i == n && a[i] == a[1])
                flag ++;
        }
    //    cout << "flag : " << flag << endl; 
        if(flag == n){
            puts("1");
            for(int i = 1;i <= n; ++ i)
                printf("1 ");
            puts("");
            return ;
        }
        if(n % 2 == 0){
            puts("2");
            for(int i = 1;i <= n / 2; ++ i){
                printf("1 2 ");
            }
            puts("");
            return ;
        }
        else{
            if(flag == 0){
                puts("3");
                for(int i = 1;i <= n / 2; ++ i)
                    printf("1 2 ");
                puts("3");
                return ;
            }
            else{
                flag = 1;
                puts("2");
                int cnt = 1;
                for(int i = 1;i <= n; ++ i){
                    if(cnt > 2) cnt = 1;
                    if(i > 1 && a[i] == a[i-1] && flag){ //补一次就行 
                        ans[i] = ans[i-1];
                        cnt = ans[i-1];
                        flag = 0;
                    }
                    else
                    ans[i] = cnt;
                    cnt ++;
                    printf("%d ",ans[i]);
                }
                puts("");
            }
        }
    
    
    }
    int main()
    {
        ios_base::sync_with_stdio(false);
        int t;
        read(t);
        while(t--) solve();
    }
  • 相关阅读:
    信息安全系统设计基础第九周学习总结
    信息安全程序设计基础第五周学习总结
    信息安全程序设计基础第二周学习总结
    信息安全程序设计基础第三周总结
    ubuntu 13.10安装jdk 1.7 owen
    vim的配置文件 owen
    程序的思想是相通的,语言只是一种手段 owen
    如何删除开机系统选择 owen
    easybcd添加或删除启动选项 owen
    星际译王词库 owen
  • 原文地址:https://www.cnblogs.com/DefineWaAc/p/13033745.html
Copyright © 2011-2022 走看看