返回顶部

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<<"\n";
    }
    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<<"\n";
                goto st;
            }
        }
        cout<<1<<" "<<n-1<<"\n";
        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<<"\n";
            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<<"\n";
        else cout<<2<<"\n";
    }
    return 0;
}

D - Omkar and Circle

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

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<<"\n";
    return 0;
}
posted @ 2020-07-12 16:11  Charles1999  阅读(322)  评论(2编辑  收藏  举报