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;        

    }
}
 

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;
        }

    }
}

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;
    }
}

D题

应该可以用莫队算法解决,下午补上

原文地址:https://www.cnblogs.com/ctyakwf/p/12255243.html

时间: 2024-10-08 20:43:44

Codeforces Round #616 题解的相关文章

Codeforces Round #616 (Div. 2)解题报告

Codeforces Round #616 (Div. 2)解题报告 A. Even But Not Even 找两个奇数就行了. #include<bits/stdc++.h> using namespace std; void solve() { int n; string s; cin >> n >> s; string ans = ""; for(int i = 0; i < n; i++) { if(int(s[i] - '0')%2

Codeforces Round #541 题解

codeforces Round #541 C 题意 给你100个人,让你将它们围成一个圆,使得:"任意相邻的两人身高差的绝对值" 中的最大值 最小 题解 显然的构造方法:先排序,让所有人1 2 报数,报2的出列,排尾变排头接到报 1 的原队列后面 证明: 显然这样的构造方法保证身高差最大为 max{(a[i+2]-a[i]) }(i=1..n,环状,a[i]升序): 我们可以说明对于任意的i,身高差至少为(a[i+2]-a[i]), 如果我们将每个人看成一个点,相邻关系看成一条无向边

CFEducational Codeforces Round 66题解报告

CFEducational Codeforces Round 66题解报告 感觉丧失了唯一一次能在CF上超过wqy的机会QAQ A 不管 B 不能直接累计乘法打\(tag\),要直接跳 C 考虑二分第\(k\)小的值 那么问题就变成了 每一个数变成了\([x-mid,x+mid]\)的一段区间,如果有一个位置被覆盖了超过\(k\)次 那么\(mid\)一定合法 类似括号匹配 每次碰到左端点就贡献+1 右端点就统计答案然后-1 维护答案的同时顺便维护位置就好了 #include<cstdio>

codeforces Round#332Div2 题解

codeforces Round#332Div2 AB 签到题 比较激动,纷纷WA了一发. C 把数组h复制给a,然后对a数组排序. 对h和a数组,求前缀和,有多少个位置满足\(\sum a[i] = \sum h[i]\), 就最多能分成多少块. D 我们枚举更短的那条边,这样的边不会太多. 然后求,更长的那条边. E 符合xxx限定条件的图的计数问题.数据范围很状压. 我们用dp[mask][root]表示,集合mask里的点,以root为根,不违背限定条件的方案数. 接下来考虑dp[mas

Codeforces Round #616 部分题解

老年选手诈尸? A,B 咕了. C - Prefix Enlightenment 很容易看出这个限制条件可以推出每个点最多被两个集合包含.按照套路,很容易联想到给这两个集合连一条边,表示他们的状态要相同/不同. 因为保证了有解,所以从左往右扫的时候拿并查集维护一下每个连通块的二分图情况,选较小的那一边. 如果只被一个集合覆盖,那么就相当于强制这个集合选/不选,在做并查集的时候特判一下即可. 代码咕了. D - Coffee Varieties (hard version) 作为一名憨憨,做法当然

Codeforces Round #616 (Div. 2) 题解

A. Even But Not Even 题意: 定义一个数所有位置的和为偶数它本身不为偶数的数为ebne,现在给你一个数字字符串,你可以删除任意位置上的数字使其变为ebne输出任意改变后的结果,如果不能则输出-1 思路: 比赛的时候分类讨论过的...真是愚蠢至极妈的 其实只要看字符串中奇数的个数就好了,如果小于两个则肯定不行,如果大于两个则直接按相对位置输出任意两个就好了 #include<iostream> #include<algorithm> #include<str

Codeforces Educational Codeforces Round 54 题解

题目链接:https://codeforc.es/contest/1076 A. Minimizing the String 题意:给出一个字符串,最多删掉一个字母,输出操作后字典序最小的字符串. 题解:若存在一个位置 i 满足 a[i] > a[i+1],若不删除 a[i] 则后续操作不可能更优. 1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define ull unsigned

Educational Codeforces Round 55 题解

题解 CF1082A [Vasya and Book] 史上最难A题,没有之一 从题意可以看出,翻到目标页只有三种办法 先从\(x\)到\(1\),再从\(1\)到\(y\) 先从\(x\)到\(n\),再从\(n\)到\(y\) 直接从\(x\)到\(y\) 三种的必要条件分别是 \((y-1)\mod d \equiv 0\) \((n-y)\mod d \equiv 0\) \(|x-y|\mod d \equiv 0\) 所以如果上面三种都不满足的话就输出\(-1\) 不然就取最小的输出

Codeforces Round 596 题解

万幸的是终于碰上了一场上分好场. 不幸的是一开始差点不会 A. 万幸的是想了个不那么稳的结论过了 pretest. 不幸的是罚时很高,而且慌得一比. 万幸的是然后半个小时内把 B 和 C 码了. 不幸的是然后就只能看着排名一点一点掉了. 万幸的是最后 A 没被叉掉. 不幸的是我居然没敢去叉人. 万幸的是我就是叉了 10 个人排名也不会上涨超过 5. 不幸的是我每掉一名都会少涨两三分. 万幸的是我没去打隔壁的 ZR. 不幸的是我发现这场 ZR 我一题不会,打了就会掉分-- 2A 没仔细想,但是应该