Codeforces Round #652 (Div. 2)部分题解

太久没打比赛果然还是变菜了

这场div2 前三题都不难
传送门

A.FashionabLee
题意:正n边形,如果存在两条边,一条边平行于x轴,一条边平行于y轴,则输出yes,否则输出no
思路:我当时的想法是,我们先选择任意一条边与y轴平行,然后由于是正n边形,每个外角为 θ = 360 n \theta=\frac{360}{n} θ=n360 。每条边就是往这个方向偏移了 θ \theta θ,那么要偏移到与x轴平行,则需要正好偏移 90 360 n = n 4 \frac{90}{\frac{360}{n}}=\frac{n}{4} n36090=4n条边,也就是说n必须是四的倍数。

所以不上代码了,得到结论后判断是不是4的倍数即可。

B.AccurateLee
题意:给定一个01字符串S(只有0和1),如果出现10这种形式,即1在前面0在后面,那么你可以选择消除1或者0中间的某一个。给你一个字符,问你最短能消除成什么样子。
思路:我们需要知道,1和0中间的任意字符都是可以消除的。比方说1和0之间有很多1,那么利用一个0就可以全部消除了。所以我们只需要找到第一个1和 最后一个0即可。由于要求字典序最小,所以把这部分全部消除变成0即可。

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int main(){

    int n;
    cin>>n;
    while(n--){
        int t;
        cin>>t;
        string s,str;
        cin>>s;
        if(t==1){
            cout<<s<<endl;
            continue;
        }
        int flag1=-1,flag2=-1;
        for(int i=0;i<t;i++){
            if(s[i]=='1'){
                flag1=i;
                break;
            }
        }
        for(int i=t-1;i>0;i--){
            if(s[i]=='0'){
                flag2=i;
                break;
            }
        }

        if(flag2<flag1||flag1==-1||flag2==-1) cout<<s<<endl;
        else {
            str=s.substr(0,flag1)+s.substr(flag2,t-flag2);
            cout<<str<<endl;
        }

    }

    return 0;
}

C.RationalLee
题意: 你需要把n个数字分给k个人,你需要使得结果sum最大。sum的计算方法为每个人得到的数字最大值和最小值的和。如果某个人只有一个数字,那么就相当于这个数字*2

思路:这题其实不难。首先先把最大的数分给只需要分一个数字的人。再把其它数字排序后,每次给人分配一个最大的以及多个最小的。注意要讲需要讲人按需要分配的数量进行降序排列。这样才能保证小数尽可能地被前一个人包括进去了。我之前没有考虑这一点,所以少加了一个sort,导致WA2

#include <bits/stdc++.h>
using namespace std;
const int N=2e5+5;
typedef long long ll;
int a[N],b[N];
bool cmp(const int a,const int b){
    return a>b;
}
int main (){
    int t;
    cin>>t;
    while(t--){
        int n,k;
        cin>>n>>k;
        ll sum=0;
        for(int i=0;i<n;i++){
            cin>>a[i];
        }
        sort(a,a+n);
        int index=n-1;
        int st=0;
        for(int i=0;i<k;i++){
                cin>>b[i];
            if(b[i]==1){
                sum+=(ll)(a[index]+a[index]);
                index--;
            }
        }
        sort(b,b+k,cmp);
        for(int i=0;i<k;i++){
            if(b[i]==1){
                continue;
            }
            sum+=(a[index]+a[st]);
            st+=b[i]-1;
            index--;
        }
        cout<<sum<<endl;
    }

    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值