• Codeforces Round #690 (Div. 3)


    头一次比赛的时候能做出6个题,最后没时间了不然就能ak了...不过这次确实简单...希望ak早日到来吧

    A. Favorite Sequence

    大意:

    给出一个数组,要求依次输出第一个、倒数第一个、第二个、倒数第二个.....

    思路:

    模拟即可

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int N = 1e6 + 5;
    typedef long long LL;
    int n, t,a[N];
    int main(){
        cin>>t;
        while(t--){
            cin >> n;
            for (int i = 0; i < n;i++){
                cin >> a[i];
            }
            for (int i = 0; i < n;i++){
                if(i%2==0){
                    cout << a[i/2]<<' ';
                }
                else{
                    cout << a[n - i/2-1]<<' ';
                }
            }
            cout << endl;
        }
        return 0;
    }
    

    B. Last Year's Substring

    大意:

    给出一个数字组成的字符串,问能否删掉一个连续的区间,使得最后字符串变为“2020”

    思路:

    直接判断2020是否在首尾两端或者是一部分在开头一部分在结尾即可

    #include<bits/stdc++.h>
    
    using namespace std;
    
    const int N = 1e6 + 5;
    typedef long long LL;
    int t, n;
    int main(){
        cin >> t;
        while(t--){
            cin >> n;
            string s;
            cin >> s;
            if (s.length() < 4) cout << "NO" << endl;
            else if(s.substr(0,4)=="2020"||s.substr(n-4,n)=="2020")
                cout << "YES" << endl;
            else if((s.substr(0,1)=="2"&&s.substr(n-3,n)=="020")||(s.substr(0,3)=="202"&&s.substr(n-1,n)=="0"))
                cout << "YES" << endl;
            else if((s.substr(0,2)=="20"&&s.substr(n-2,n)=="20"))
                cout << "YES" << endl;
            else
                cout << "NO" << endl;
        }
        return 0;
    }
    

    C. Unique Number

    大意:

    给出一个数x((1<=x<=50)),问能否找到一个数,这个数的每一位都不相同,且每一位加起来的和等于x,如果有多个,输出最小的那个

    思路:

    直接打表判断即可

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 1e6 + 5;
    typedef long long LL;
    int t, n;
    int main() {
        /*
        for (int i = 1; i <= 50; i++) {
            int can = 0;
            for (LL j = 1; j <= 999999999 && can == 0; j++) {
                LL temp = j;
                int cnt[20];
                int sum = 0;
                memset(cnt, 0, sizeof cnt);
                while (temp) {
                    int tt = temp % 10;
                    cnt[tt]++;
                    temp /= 10;
                    sum += tt;
                }
                int flag = 0;
                for (int k = 0; k <= 9; k++) {
                    if (cnt[k] > 1) {
                        flag = 1;
                        break;
                    }
                }
                if (flag) {
                    continue;
                }
                if (sum == i) {
                    can = 1;
                    cout << j << ',' ;
                }
            }
        }*/
        LL res[50] = {1,        2,        3,         4,       5,       6,
                      7,        8,        9,         19,      29,      39,
                      49,       59,       69,        79,      89,      189,
                      289,      389,      489,       589,     689,     789,
                      1789,     2789,     3789,      4789,    5789,    6789,
                      16789,    26789,    36789,     46789,   56789,   156789,
                      256789,   356789,   456789,    1456789, 2456789, 3456789,
                      13456789, 23456789, 123456789, -1,      -1,      -1,
                      -1,       -1};
        cin>>t;
        while(t--){
            cin >> n;
            cout << res[n - 1] << endl;
        }
        return 0;
    }
    

    D. Add to Neighbour and Remove

    大意:

    给出一个数组,每次操作可以选择一个数,将其加入左边或者右边的数,然后删掉这个数,问经过多少次操作可以将数组变为全部元素相等的数组。

    思路:

    可以想到最后的状态必然是多个区间和相等,那么直接先对原始的数组求和,然后求这个和的约数,枚举每个约数,看能否将数组划分为多个等于这个约数的区间即可

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long LL;
    int const N = 3e5 + 10;
    int a[N];
    LL sum[N];
    vector<LL> yuenum;
    int quchong[233];
    // 试除法求约数
    vector<LL> get_divisors(LL x) {
        vector<LL> res;                                // 记录答案
        for (int i = 1; i <= x / i; ++i) {             // 枚举到sqrtx(x)
            if (x % i == 0) {                          // 如果能够整除
                res.push_back(i);                      // 放入i
                if (i != x / i) res.push_back(x / i);  // x/i不等于i,也放入答案中
            }
        }
        sort(res.begin(), res.end());  // 排序
        return res;
    }
    
    int t, n;
    int main() {
        cin >> t;
        while (t--) {
            cin >> n;
            LL temp = 0;
            for (int i = 1; i <= n; i++) {
                cin >> a[i];
                sum[i] = sum[i - 1] + a[i];
                temp += a[i];
            }
            yuenum = get_divisors(temp);
            LL res = 0x3f3f3f3f;
            for (int k = 0; k < yuenum.size(); k++) {
                LL pre = 0;
                int f = 1;
                for (int i = 1; i <= n; i++) {
                    pre += a[i];
                    if (pre == yuenum[k]) {
                        pre = 0;
                    }
                    if (pre > yuenum[k]) {
                        f = 0;
                        break;
                    }
                }
                if (f!=0) res = min(res, n-temp/yuenum[k]);
            }
            cout<<res<<endl; 
        }
        return 0;
    }
    

    E1. Close Tuples (easy version)

    大意:

    建议先看E2

    相比于E2,只是限定了m=3,k=2,而且不取模。

    思路:

    做完E2之后直接把m=3 k=2改了交了,结果wa了...仔细想想发现不需要这么麻烦,因为m很小,直接手动算组合数即可

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long LL;
    
    LL const N = 3e5 + 10, mod = 1e18;
    
    int  t, n, m, k;
    int  a[N];
    int  main() {
        cin >> t;
        while (t--) {
            cin >> n;
            m = 3;
            k = 2;
            for (int i = 0; i < n; i++) {
                cin >> a[i];
            }
            LL res = 0;
            sort(a, a + n);
            for (int i = 0; i < n; i++) {
                int  pos = upper_bound(a, a + n, a[i]+k) - a - 1;
                if (pos - i + 1 < m) continue;
                res += ((LL)pos - (LL)i )*((LL)pos - (LL)i -1)/2;
            }
            cout << res << endl;
        }
        return 0;
    }
    

    E2. Close Tuples (hard version)

    大意:

    给出n个数,以及m和k,问能找出多少组数,满足:每组里面有m个数,且这组数里面的最大值与最小值之差不大于k

    思路:

    先将数组排一下序,然后对于每个数,都upper_bound找一下比这个数大k的最大的数的下标pos,如果下标的差大于等于m,则答案+=(C_{m-1}^{pos-i})即可,代表以这个数为最小值有多少种取法。

        #include <bits/stdc++.h>
         
        using namespace std;
         
        typedef long long LL;
         
        int const N = 3e5 + 10, mod = 1e9 + 7;
        int fact[N], infact[N];
         
         
        LL qmi(LL a, LL k, LL p) {
            LL res = 1;
            while (k) {
                if (k & 1) res = res * a % p;
                k >>= 1;
                a = a * a % p;
            }
            return res;
        }
         
        // 预处理
        void init() {
            fact[0] = infact[0] = 1;
            for (int i = 1; i < N; ++i) {
                fact[i] = (LL)fact[i - 1] * i % mod;
                infact[i] = (LL)infact[i - 1] * qmi(i, mod - 2, mod) % mod;
            }
        }
         
        int t, n, m, k, a[N];
        int main() {
            init();
            cin >> t;
            while (t--) {
                cin >> n >> m >> k;
                for (int i = 0; i < n; i++) {
                    cin >> a[i];
                }
                LL res = 0;
                sort(a, a + n);
                for (int i = 0; i < n; i++) {
                    int pos = upper_bound(a, a + n, a[i]+k) - a - 1;
                    if (pos - i + 1 < m) continue;
                    //cout << "yes" << endl;
                    res += (LL)fact[pos - i ] * infact[m-1] % mod *
                           infact[pos - i + 1 - m] % mod;
                    res = res % mod;
                }
                cout << res << endl;
            }
            return 0;
        }
    

    F. The Treasure of The Segments

    大意:

    给出n个区间,问最少需要删去多少个区间,使得剩下的区间满足至少有一个区间和其他所有剩下的区间都相交

    思路:

    一开始想枚举每个区间然后算有哪些区间和它相交,写了一发发现不对,没有考虑被它包含的情况,后来发现只需要直接求和它不相交的区间有多少即可。

    和区间i不相交的区间j满足:

    j的右区间小于i的左区间 或者 j的左区间大于i的右区间

    所以只需要两次按照端点排序,分别二分即可

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 1e6 + 5;
    typedef long long LL;
    int t, n, temp[N];
    struct node {
        int l, r, ln, rn;
    } a[N];
    
    bool cmpl(node a, node b) { return a.l < b.l; }
    bool cmpr(node a, node b) { return a.r < b.r; }
    int main() {
        cin >> t;
        while (t--) {
            cin >> n;
            for (int i = 0; i < n; i++) {
                cin >> a[i].l >> a[i].r;
                a[i].ln = a[i].rn = 0;
            }
            sort(a, a + n, cmpl);
            for (int i = 0; i < n; i++) {
                temp[i] = a[i].l;
            }
            for (int i = 0; i < n; i++) {
                int pos = upper_bound(temp, temp + n, a[i].r) - temp;
                a[i].rn = n-pos;
            }
            sort(a, a + n, cmpr);
            for (int i = 0; i < n; i++) {
                temp[i] = a[i].r;
            }
            for (int i = 0; i <n; i++) {
                int pos = lower_bound(temp, temp + n, a[i].l) - temp-1;
                a[i].ln = pos + 1;
            }
            int res = 0x3f3f3f3f;
            for (int i = 0; i < n; i++) {
                res = min(a[i].ln + a[i].rn, res);
            }
            cout << res << endl;
        }
        return 0;
    }
    
  • 相关阅读:
    MySQL实现嵌套集合模型
    Go项目结构和模块导入
    sqlalchemy(二)高级用法
    sqlalchemy(一)基本操作
    K-均值聚类算法
    回归
    logistic回归
    Android隐藏状态栏、导航栏
    Android监听返回键、Home键+再按一次返回键退出应用
    PDFMate PDF Converter Pro
  • 原文地址:https://www.cnblogs.com/dyhaohaoxuexi/p/14147625.html
Copyright © 2020-2023  润新知