Codeforces Round #655 (Div. 2)【ABCD】(题解) 涵盖知识点:思维、前缀和

比赛链接:传送门

A - Omkar and Completion

题意: 要求构造一个长度为(n)的数组满足任意两个数相加不等于第三个数
题解:(1)即可
Accept Code:

#include <bits/stdc++.h>
using namespace std;

int main(){
    int t;cin>>t;
    while(t--){
        int n;
        cin>>n;
        for(int i=0;i<n;i++)cout<<"1 ";
        cout<<"
";
    }
    return 0;
}

B - Omkar and Last Class of Math

题意: 给定(n),要求找到一组(a,b)满足(a+b=n)(LCM(a,b))尽可能小。
题解: 要使(LCM)尽可能小,那么(GCD)就要尽可能大,从小到大枚举(n)的因子即可。
Accept Code:

#include <bits/stdc++.h>
using namespace std;

int main(){
    int t;cin>>t;
    while(t--){
        int n;
        cin>>n;
        for(int i=2;i<=sqrt(n);i++){
            if(n%i==0){
                cout<<n/i<<" "<<n-n/i<<"
";
                goto st;
            }
        }
        cout<<1<<" "<<n-1<<"
";
        st:;
    }
    return 0;
}

C - Omkar and Baseball

题意: 给定一种操作可以使得某区间内所有数字任意排列,但是要满足所有数字都不能在自己原来的位置上。问多少次操作可以将原本的乱序排列变为递增排列。
题解: 分类讨论。原本就满足条件:0;原本全乱序:1;原本除前缀和后缀外全乱序:1;其他情况:2.证明自行脑补一下。
Accept Code:

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int a[maxn];
int main(){
    int t;cin>>t;
    while(t--){
        int n;
        cin>>n;
        int ans=0;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            if(a[i]==i)ans++;
        }
        if(ans==n){
            cout<<0<<"
";
            continue;
        }
        for(int i=1;i<=n;i++){
            if(a[i]==i)ans--;
            else break;
        }
        for(int i=n;i>=1;i--){
            if(a[i]==i)ans--;
            else break;
        }
        if(ans==0)cout<<1<<"
";
        else cout<<2<<"
";
    }
    return 0;
}

D - Omkar and Circle

题意: (n)个数字组成一个环,每次操作选择一个数并将其变为两个相邻数字的和并删除相邻数字。通过若干次操作最后会只剩下一个数字。(因为(n)为奇数)。问这个数字最大是多少
题解: 在纸上自己操作几次之后,就会发现在确定断点以后,相邻位置的数字无论怎么变化一定会合并,只是顺序不同。所以按照奇偶性计算一下前缀和并两倍延长一下取区间最大值即可。
UPD: 图片仅作示意,思路推导过程。
Codeforces Round #655 (Div. 2)【ABCD】(题解)
涵盖知识点:思维、前缀和

Accept Code:

#include <bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
typedef long long ll;
ll a[maxn<<1],sum[maxn<<1];

int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i],a[i+n]=a[i];
    sum[1]=a[1];
    for(int i=2;i<=n*2;i++)sum[i]=sum[i-2]+a[i];
    ll ans=0;
    for(int i=n+1;i<=2*n;i++)ans=max(ans,sum[i]-sum[i-n-1]);
    cout<<ans<<"
";
    return 0;
}