CodeCraft-22 and Codeforces Round #795 (Div. 2)(A-C)题解

A. Beat The Odds

题目链接:Problem - A - Codeforces

题意:给出n个数,每次操作可以删除一个数,最终使得序列中每相邻两个数之和为偶数,求最少操作数。

思路:要么只有奇数,要么只有偶数。取奇数个数和偶数个数的最小值即可。

AC code:

#include <bits/stdc++.h>

using namespace std;
int n,a[100010]; 
int main(){
    int t;
    cin>>t;
    while(t--){
        cin>>n;
        int cnt1=0;
        int cnt2=0;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            if(a[i]&1) cnt1++;
            else cnt2++;
        }
        cout<<min(cnt1,cnt2)<<endl;
    }
    return 0;
} 

B. Shoe Shuffling

题目链接:Problem - B - Codeforces

题意:给你一个非下降序列,让你打乱这些数,使得每个数所在的位置不在原来的位置。当且仅当a[i]>a[j]时,这两个数可以交换,判断是否能够满足题意,如果可以满足题意,输出原来数的位置被交换后的位置,否则输出-1。

思路:当一个数仅出现一次时,一定不能满足题意,若每个数都出现两次以上则满足题意,交换下标即可。

AC code:

#include <bits/stdc++.h>

using namespace std;
int n,a[100010];
void solve(){
    cin>>n;
    vector<array<int,2>> v;
    for(int i=0;i<=n+1;i++) a[i]=-1;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    for(int i=2;i<=n-1;i++){
        if(a[i]!=a[i-1] && a[i]!=a[i+1]){
            cout<<-1<<endl;
            return ;
        }
    }
    if(a[1]!=a[2] || a[n-1]!=a[n]){
        cout<<-1<<endl;
        return ;
    }
    int i=1;
    int cnt=1;
    while(i<=n){
        if(a[i]!=a[i+1]){
            v.push_back({i,cnt});
            i++;
            cnt=1;
        }else{
            cnt++;
            i++;
        }
    }
    for(auto [x,y]:v){
        cout<<x<<' ';
        for(int i=x-y+1;i<=x-1;i++){
            cout<<i<<' ';
        }
    }
    cout<<endl;
}
int main(){
    int t;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
} 

赛时没有check a[1]和a[n],哭死。

C. Sum of Substrings

题目链接:Problem - C - Codeforces

题意:给你一段01串,相邻两个数字组成一个十位数,求这n-1个十位数的最小值,有k次操作,每次可以交换相邻两个数。

思路:头部的1对答案的贡献为10,尾部的1对答案的贡献为1,中间的1 对答案的贡献为11,因此优先将1移到尾部,然后再考虑移动到头部。

AC code :

#include <bits/stdc++.h>

using namespace std;
int n,k;
string s;
int main(){
    int t;
    cin>>t;
    while(t--){
        cin>>n>>k>>s;
        s='#'+s;
        long long ans=0;
        for(int i=1;i<n;i++){
            int t=(s[i]-'0')*10+(s[i+1]-'0');
            ans+=t;
        }
        int pos1=0,pos2=0;
        for(int i=n;i>=1;i--){
            if(s[i]=='1'){
                pos1=i;
                break;
            }
        }
        for(int i=1;i<=n;i++){
            if(s[i]=='1'){
                pos2=i;
                break;
            } 
        }
        if(pos1==0){
            cout<<ans<<endl;
            continue;
        }
        if(pos1==pos2){
            if(pos1!=n){
                if(k>=n-pos1){
                    ans-=10;
                    if(pos1==1){
                        ans++;
                    }
                }else if(k>=pos2-1 && pos2!=1) ans--;
            }
        }else{
            if(k>=n-pos1 && pos1!=n){
                ans-=10;
                k-=n-pos1;
            }
            if(k>=pos2-1 && pos2!=1){
                ans--;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值