返回顶部

Codeforces Round #661 (Div. 3)【ABCD】(题解)

涵盖知识点:思维

比赛链接:传送门

A - Remove Smallest

题意: 每次选择两个相差\(1\)以内的数字删除较小的一个,若两数相等,则随机删除一个。问最后能否删到只剩一个数字。
题解: 排序一下观察是否连续即可。
Accept Code:

#include <bits/stdc++.h>
using namespace std;
int a[110];
int main(){
    int t;cin>>t;
    while(t--){
        int n;
        cin>>n;
        for(int i=0;i<n;i++)cin>>a[i];
        sort(a,a+n);
        for(int i=1;i<n;i++){
            if(a[i]-a[i-1]>1){
                puts("NO");
                goto st;
            }
        }
        puts("YES");
        st:;
    }
    return 0;
}

B - Gifts Fixing

题意: \(n\)份物品,每份都有\(a,b\)两种值。现在每次操作可以选择将其中一份的\(a\)减一或者\(b\)减一或者同时减一。问至少几次操作可以使得所有物品的\(a\)值相同,且所有物品的\(b\)值相同。
题解: 很容易看出来最后的结果一定是将\(a\)减为所有\(a\)的最小值,\(b\)也同理,那么贪心,同时有相减需求的同时相减,否则单独减即可。
Accept Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=110;
const int inf=1e9+10;
int a[maxn],b[maxn];
int main(){
    int t;cin>>t;
    while(t--){
        int n;
        cin>>n;
        int ma=inf,mb=inf;
        for(int i=0;i<n;i++)cin>>a[i],ma=min(ma,a[i]);
        for(int i=0;i<n;i++)cin>>b[i],mb=min(mb,b[i]);
        ll ans=0;
        for(int i=0;i<n;i++){
            int aa=a[i]-ma,bb=b[i]-mb;
            ans+=max(aa,bb);
        }
        cout<<ans<<"\n";
    }
    return 0;
}

C - Boats Competition

题意:\(n\)个数分成尽可能多的若干二人组,使得每组的数值之和都相等。
题解: 直接暴力\(0\)\(100\)的所有可能性。
Accept Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=110;
const int inf=1e9+10;
int cnt[maxn];
int main(){
    int t;cin>>t;
    while(t--){
        int n;
        cin>>n;
        memset(cnt,0,sizeof cnt);
        for(int i=0,x;i<n;i++){
            cin>>x;
            cnt[x]++;
        }
        int ans=0;
        for(int i=0;i<=100;i++){
            int res=0;
            for(int j=1;j<=i/2;j++)res+=min(cnt[j],cnt[i-j]);
            if(i%2==0)res+=cnt[i/2]/2-cnt[i/2];
            ans=max(ans,res);
        }
        cout<<ans<<"\n";
    }
    return 0;
}

D - Binary String To Subsequences

题意: 将一个01串拆为若干个子序列,使得每个子序列中不含连续的1和0
题解: 贪心,队列维护一下当前子序列的序号,当且仅当之前没有构造出来符合条件的时候增加序列的序号。
Accept Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e5+10;
const int inf=1e9+10;
int ans[maxn];
int main(){
    int t;cin>>t;
    while(t--){
        int n;
        cin>>n;
        string s;
        cin>>s;
        int cnt=0;
        ans[0]=1;
        queue<int> q0,q1;
        for(int i=0;i<n;i++){
            int tmp;
            if(s[i]=='1'){
                if(q0.empty()){
                    cnt++;
                    q1.push(cnt);
                    tmp=cnt;
                }
                else{
                    tmp=q0.front();
                    q0.pop();
                    q1.push(tmp);
                }
            }
            else{
                if(q1.empty()){
                    cnt++;
                    q0.push(cnt);
                    tmp=cnt;
                }
                else{
                    tmp=q1.front();
                    q1.pop();
                    q0.push(tmp);
                }
            }
            ans[i]=tmp;
        }
        cout<<cnt<<"\n";
        for(int i=0;i<n;i++)cout<<ans[i]<<" ";
        cout<<"\n";
    }
    return 0;
}
posted @ 2020-08-07 17:39  Charles1999  阅读(139)  评论(0编辑  收藏  举报