zoukankan      html  css  js  c++  java
  • codeforces Round #632 (Div. 2)C. D.F题解

    Codeforces Round 632 (Div. 2)C. D.F题解

    比赛链接

    C - Eugene and an array

    题意:

    求一个array的有多少subarray是good的,subarray定义为子串,必须怜恤。一个array是good的条件是其全部subarray的和不为0。

    题解:

    求一个前缀和,使用map保存每一个前缀和的下标,一旦出现相同的前缀和,就是出现和为0的串,所以全部串都不应该包括它。

    代码:

    #include <iostream>
    #include <stdio.h>
    #include <cstring>
    #include <map>
    using namespace std;
    const  int N=2e5+10;
    #define ll long long
    int a[N];
    map<ll,int>pos;
    int main() {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        ll sum =0;
        int p=-1;
        ll ans = 0;
        pos[0]=0; //important
        for(int i=1;i<=n;i++) {
            sum += a[i];
            if (pos.count(sum))p = max(p, pos[sum]);
            ans += i - (p + 1);
            pos[sum] = i;
        }
        printf("%lld
    ",ans);
        return 0;
    }
    

    D - Challenges in school №41

    题意:

    变形的等价问题为,输入0,1串,每次可以交换任意组(最少一组)的连续的两个0,1的位置,最后使得全部1在左边,全部0在右边。求构造一个恰好交换k次的方案。输出每次交换的每组中1的位置

    题解:

    有点类似冒泡排序,把1全部冒到左边即可。
    最小的min_k:每次交换全部的全部相邻的0,1对。
    最大的max_k:每次交换一组0,1队。
    输入的k必须位于二者之间。
    用最小的min_k转换到任意一个满足条件的k(代码细节学dls写的。

    代码:

    #include <iostream>
    #include <stdio.h>
    #include <cstring>
    #include <map>
    #include <algorithm>
    #include <math.h>
    #include <vector>
    using namespace std;
    const int  N=3005;
    char arr[N];
    int main() {
        int n,k;
        scanf("%d%d",&n,&k);
        scanf("%s",arr);
        vector<vector<int> > ps = vector<vector<int>>(k,vector<int>());
        int tol = 0;
        int m=0;
        while (1) {
            vector<int> step;
            for (int i = 0; i < n - 1; i++) {
                if (arr[i] == 'R' && arr[i + 1] == 'L')step.push_back(i), tol++;
            }
                if (step.empty())break;
                if (m >= k) {
                    puts("-1");
                    return 0;
                }
                ps[m++] = step;
                for (auto x:step)swap(arr[x], arr[x + 1]);
            }
            if(k>tol){
                puts("-1");
                return 0;
            }
            int fs = m-1;//最少的
            for(int i=k-1;i>=0;i--){
                if(ps[fs].empty())fs--;
                if(!ps[i].empty())break;
                ps[i] = vector<int>{ps[fs].back()};
                ps[fs].pop_back();
            }
            for(int i=0;i<k;i++){
                printf("%d ",ps[i].size());
                for(auto x:ps[i])printf("%d ",x+1);
                puts("");
            }
     
        return 0;
    }
    

    F. Kate and imperfection

    题意:

    在1~n的n个数中,对于k∈[2,n],在n个数中取k个数,选出k的数,使得他们最大gcd最小。

    题解:

    素数筛类似。
    因为求的是最大gcd的最小,所以我们先尽可能的拿素数,素数拿完以后,再拿一个数,必然有一对不互质,所以我们要尽量使答案变小,即因子小的先拿,最后就可以得到从小到大输出的结论。
    这样逻辑似乎还是有点问题,依然不能证明这就是最优方案。

    代码:

    #include <iostream>
    #include <stdio.h>
    #include <cstring>
    #include <map>
    #include <algorithm>
    #include <math.h>
    using namespace std;
    const  int N=5e5+10;
    #define ll long long
    int a[N];
    int pr[N];
    map<ll,int>pos;
    void solve(int n){
        for(int i=1;i<=n;i++)pr[i]=1;
        for(int i=2;i<=n;i++){
            for(int j=2*i;j<=n;j+=i){
                pr[j] = i;//目前的最大因子
            }
        }
    }
    int main() {
        int n;
        scanf("%d",&n);
        solve(n);
        sort(pr+1,pr+n+1);
        for(int i=2;i<=n;i++){
            printf("%d ",pr[i]);
        }
     
     
        return 0;
    }
    
  • 相关阅读:
    mysql分组排序取组内第一的数据行
    C#版Nebula客户端编译
    关于nginx
    http状态码
    gitlab
    TCP/IP 3次握手和四次断开
    nps 内网穿透
    用CentOS7做一个简单的路由器
    linux 简单特效
    LVS粗讲
  • 原文地址:https://www.cnblogs.com/gzr2018/p/12680008.html
Copyright © 2011-2022 走看看