A. Unit Array

题意:一个操作可以将-1变成1,问最少操作几次,可以是数组的和>=0,数组的积为正数

思路:求一遍和,然后操作一次+2,求>=0的次数,再判断-1剩下的个数,若是奇数,再操作一次

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define  PII pair<int,int>
void solve(){
    int n;
    cin>>n;
    int cnt=0;
    int ans=0;
    for (int i = 0; i <n ; ++i) {
        int x;
        cin>>x;
        ans+=x;
        if(x==-1)cnt++;
    }
    int res=0;
    if(ans>=0){
        if(cnt%2==1){
            res++;
        }
    }
    if(ans<0){
        res=(ans-1)/(-2);
        if((cnt-res)%2==1){
            res++;
        }
    }

    cout<<res<<endl;

}
signed main(){
    ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
    int t=1;
    cin>>t;
    while (t--){
        solve();
    }
}

B. Maximum Strength

题意:给l和r,取两个数,使他们的各个位数的之差的和最大,最大是多少

思路:找到第一个不相等的那一位,然后做差,后面的一个取0,一个取9,即ans=abs(a[i]-b[i])+(n-i) * 9

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define  PII pair<int,int>

void solve(){
    string s1,s2;
    cin>>s1>>s2;
    if(s1.size()<s2.size()){
        swap(s1,s2);
    }
    if(s1.size()==s2.size()){
        if(s1<s2)swap(s1,s2);
    }
    while(s2.size()<s1.size()){
        s2="0"+s2;
    }
    int ans=0;
    for (int i = 0; i <s1.size() ; ++i) {
        if(s1[i]!=s2[i]){
            ans+=s1[i]-s2[i];
            ans+=9*s1.size()-(i+1)*9;
            break;
        }
    }
    cout<<ans<<endl;

}
signed main(){
    ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
    int t=1;
    cin>>t;
    while (t--){
        solve();
    }
}

C. Game with Reversing

题意:给定两个字符串,a的操作是改变一个字符串的字符,b的操作是翻转一个字符串,问几次操作可以使两字符串相等。

思路:我们贪心的想,其实我们有两种情况,一种是让他们相等,另一种是互为回文,枚举每一种情况,共四个ans,取最小即可

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define  PII pair<int,int>

void solve(){
    int n;
    cin>>n;
    string s1;
    string s2;
    cin>>s1>>s2;
    int res1=0,res2=0;
    for (int i = 0; i <n ; ++i) {
        if(s1[i]!=s2[i]){
            res1++;
        }
        if(s1[i]!=s2[n-i-1])res2++;
    }
    if(!res1){
        cout<<"0\n";
        return;
    }
    if(!res2){
        cout<<"2\n";
        return;
    }
    if(res2%2==0) {
        res2=res2*2+-1;
    }
    else{
        res2=res2*2;
    }
    if(res1%2==1) {
        res1=res1*2-1;
    }
    else{
        res1=res1*2;
    }
    cout<<min(res2,res1)<<endl;

}
signed main(){
    ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
    int t=1;
    cin>>t;
    while (t--){
        solve();
    }
}

D. Survey in Class

题意:

给定n个区间,你需要选择一些整数,作为集合s,一个区间的得分定义为,对于s中的每一个数,如果在该区间内,得分加一,否则减一,可为负,按照该规则计算每一个区间的得分,问最大分和最小得分的分差最大值是多少?

思路:

比如一个区间是1到5,另一个离他最远的区间4到8,则贡献值就是1到3然后乘以2,即6;那么我们分为三种情况

  • 1 当我们计算这个区间的最大贡献时,离他右边最远的那个区间的l,贡献就是 min(r[i],lmax-1)-l[i]+1
  • 2 离他左边最远的那个区间的r,贡献就是 r[i]-max(rmin,l[i]-1)
  • 3 其次就是有区间在这个区间之内,贡献就是r[i]-l[i]- minlen+1

最后记得乘2;

代码:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define  PII pair<int,int>

void solve(){
    int n,m;
    cin>>n>>m;
    vector<int>l(n+1),r(n+1);
    int lmax=0,rmin=1e9;
    int minlen=1e9;
    for (int i = 1; i <=n ; ++i) {
        cin>>l[i]>>r[i];
        lmax=max(l[i],lmax);
        rmin=min(r[i],rmin);
        minlen=min(minlen,r[i]-l[i]+1);
    }
    int ans=0;
    for (int i = 1; i <=n ; ++i) {
        ans= max({ans,r[i]-max(rmin,l[i]-1),min(r[i],lmax-1)-l[i]+1,r[i]-l[i]- minlen+1});
    }
    cout<<ans*2<<endl;

}
signed main(){
    ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
    int t=1;
    cin>>t;
    while (t--){
        solve();
    }
}
posted on 2023-07-18 20:03  IR101  阅读(10)  评论(0编辑  收藏  举报  来源