• Codeforces Round #616 题解


    A题

    我们注意到如果存在两个奇数,那么就能满足题目条件,所以我们就从头寻找两个奇数,没有的话就是无解

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<vector>
    #include<string>
    #include<cstring>
    #include<map>
    using namespace std;
    typedef long long ll;
    const int N=600010;
    int pos[N]={0};
    int main(){
        int t;
        cin>>t;
        while(t--){
            int n;
            string s;
            cin>>n;
            cin>>s;
            if(n==1){
            cout<<-1<<endl;
            continue;
            }
            
                int cnt=0;
                int i;
                
                for(i=0;i<s.size();i++){
                    if(cnt==2)
                    break;
                    if((s[i]-'0')%2){
                        pos[cnt++]=s[i]-'0';
                    }
                }
                if(cnt<2)
                    cout<<-1<<endl;
                else
                    cout<<pos[0]<<pos[1]<<endl;        
            
        }
    }
     
    View Code

    B题

    可以贪心的想,只要将串设计为0 1 2 3 ……3 2 1 0

    这种形式的话是最容易的满足条件的,因为每个数只要大于该数所在位置的下标就行,其他方法都没有这样好

    因此我们可以设计两个哨兵,一个l从开始枚举直到第一个不满足条件的,一个r从后面往前枚举

    如果l>=r说明满足条件,输出yes因为两边都满足这样的条件,我们只需要取l=r处为中间点,两边按自己的规律枚举即可。

    注意判断完全递增和完全递减序列

    另外,我的代码有特判一位数的情况,每个一位数都可以,和两位数并且两个都是0的情况,这是不行的,其他两位数都可以

    其实不用特判。

    我的代码中对每个数都加了1,因为我是从第一位开始枚举的,从第0位开始枚举的不用+1

     
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<vector>
    #include<string>
    #include<cstring>
    #include<map>
    using namespace std;
    typedef long long ll;
    const int N=3e5+10;
    int a[N];
    int main(){
        int t; 
        cin>>t;
        while(t--){
            int n;
            cin>>n;
            int i;
            for(i=1;i<=n;i++){
                cin>>a[i];
                a[i]+=1;
            }
            if(n==1){
                cout<<"Yes"<<endl;
            }
            else if(n==2){
                if(a[1]==1&&a[2]==1)
                cout<<"No"<<endl;
                else
                cout<<"Yes"<<endl;
            }
            else{
            int p1=-2;
            int p2=n+2;
            for(i=1;i<=n;i++){
                if(a[i]<i){
                    p1=i-1;
                    break;
                }
            }
            for(i=n;i>=1;i--){
                if(a[i]<n-i+1){
                    p2=i+1;
                    break;
                }
            }
            int flag=0;
            if(p2==n+2||p1==-2)
            flag=1;
            else if(p1>=p2)
            flag=1;
            if(flag==1)
            cout<<"Yes"<<endl;
            else
            cout<<"No"<<endl;
            }
            
            
        }
    }
    View Code

    C题

    本题看数据范围发现可以满足O(N^2)的算法,所以我们可以直接上暴力,下面有几个注意点

    1.k要更新为min(m-1,k),因为即使k再大我们控制后面的人也没有意义

    2.我们要明确一点,控制的人越多越好,这是一种贪心的思路,这也是很显然的,这样你就可以根据情况尽可能的将最大的留给自己

    3.我们需要枚举两维,代表的意思是我控制k个人中取前面的人数,和不受控制的人选前面的人数,这样就能枚举出所有情况

    tips:第二维可以使用线段树维护,这样可以降低复杂度(虽然本题数据可以暴力水过),有兴趣的同学可以取cf官网上查询官方题解

    枚举过程见代码注释

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<vector>
    #include<string>
    #include<cstring>
    #include<map>
    using namespace std;
    typedef long long ll;
    const int N=3e5+10;
    const int inf=0x3f3f3f3f;
    int a[N];
    int main(){
        int n;
        int i;
        int m,k;
        int t;
        cin>>t;
        while(t--){
            cin>>n>>m>>k;
            k=min(m-1,k);
            for(i=0;i<n;i++){
                cin>>a[i];
            }
            int ans=-inf;
            int j;
            int tmp;
            for(i=0;i<=k;i++){//k个人中我选i个取前面 
                tmp=inf;
                for(j=0;j<m-k;j++){//剩下的m-1-k人中有j个在前面 
                    tmp=min(tmp,max(a[i+j],a[i+j+(n-m)])); //轮到我取的时候我取前面还是最后面的最大值的最小值  
                }
                ans=max(ans,tmp);
            }
            cout<<ans<<endl;
        }
    }
    View Code

    D题 

    本题是一道思维构造题目,另外可以使用莫队算法记录答案。

    题意是对获得的子串,重新构造看能否成为irr的情况

    1.如果只有一个元素,那么是满足的,因为题目要求k>=2

    2.如果只有两种元素,且开头和末尾不等,那也满足条件,只需对调开头和末尾

    当开头和末尾都相等,那么就不满足,因为首先我们知道原先他们的字符总数和各个字符总数是相同的,举个例子 aaabbba

    那么我们重新构造的子串有下列可能

    b------a

    b------b

    a------b

    a------a

    对于第一种,只需要断点设在倒数第二位

    对于第二种,断点设在第一个满足前x个是alagram的位置,这样前后两段依旧满足

    对于第三种,断点设在第二位

    第四种天然满足

    所以证明。

    3.如果有不同的三个字符,显然都可以构造

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    #include<vector>
    #include<string>
    #include<cstring>
    #include<map>
    using namespace std;
    typedef long long ll;
    const int N=3e5+10;
    int pos[N];
    int cnt[N];
    int b[N];
    int ans[N];
    char s[N];
    struct node{
        int l,r;
        int k;
    }q[N]; 
    bool cmp(node a,node b){
        if(pos[a.l]==pos[b.l])
        return a.r<b.r;
        return pos[a.l]<pos[b.l];
    }
    int main(){
        int m;
        scanf("%s",s+1);
        cin>>m;
        int i;
        int n=strlen(s+1);
        int block=sqrt(n);
        for(i=1;i<=n;i++){
            b[i]=s[i]-'a'+1;
            pos[i]=(i-1)/block+1;
        }
        int l=1;
        int r=0;
        for(i=1;i<=m;i++){
            scanf("%d%d",&q[i].l,&q[i].r);
            q[i].k=i;
        }
        sort(q+1,q+1+m,cmp);
        int res=0;
        for(i=1;i<=m;i++){
            if(q[i].l==q[i].r){
                ans[q[i].k]=1;
                continue;
            }
            while(l<q[i].l) 
            res-=(!--cnt[b[l++]]);
            while(l>q[i].l) 
            res+=(!cnt[b[--l]]++);
            while(r<q[i].r) 
            res+=(!cnt[b[++r]]++);
            while(r>q[i].r) 
            res-=(!--cnt[b[r--]]);
            ans[q[i].k]=((res==2&&b[q[i].l]!=b[q[i].r]||res>2)?1:-1);
        }
        for(i=1;i<=m;i++)
        if(ans[i]==-1)
        printf("NO
    ");
        else
        puts("YES"); 
    } 
    View Code
  • 相关阅读:
    开源包管理系统和环境管理系统 Conda
    浅谈 Python 的模块导入
    用 pytest 测试 python 代码
    关于特征筛选中的IV值
    二 k-means聚类算法的手动实现
    二 统计量及其抽样分布
    PAT B1056组合数的和
    PAT B1061判断题
    'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte
    Hadoop搭建高可用的HA集群
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12255243.html
Copyright © 2020-2023  润新知