刚开比赛就看了A题,题意大意大概就是给一个序列,按照给的步骤,将数列中的 1 变成 2 ,然后将 2 变成 1 ,第三步就是 将 3 变成 4,4变成 3 。。。其实就是奇数不变,偶数减一就行了

#include <cstdio>
#include <iostream>
using namespace std;
int main()
{
    int num[100000];
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>num[i];
        if(num[i]%2==0) num[i]--;
    }
    cout<<num[0];
    for(int i=1;i<n;i++) cout<<' '<<num[i];
    return 0;
}

 B题是真的难受,换了几种方法都是是wa16,思路挺简单的,就是找出前k大的数,然后将下标记录一下,最后根据这个下标排下序,然后划分就行了,然后因为数据规模较小,用数组即可(数据大也可以用map)

贴上代码:

#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;

int main()
{
    int n,m;
    cin>>n>>m;
    int num[2001]={0};
    int a[n],b[n];
    for(int i=0;i<n;i++)
     {
      cin>>a[i];
      b[i]=a[i];
     }
     sort(a,a+n);
     int sum=0,t=0;
     for(int i=n-1;i>=0;i--)
     {
         num[a[i]]++;
        sum+=a[i];
         t++;
         if(t==m) break;
     }
     cout<<sum<<endl;
     int d=0;
     t=0;
     for(int i=0;i<n;i++)
     {
         d++;
         if(num[b[i]])
         {
              t++;
              if(t==m) cout<<d+n-(i+1)<<" ";
              else cout<<d<<" ";
              d=0;
              num[b[i]]--;
         }
     }
     return 0;
}

C题就暴力就能过,题意大概就是给一个序列,能否将这个序列分成三个部分(可以为空),满足第一序列和也第三序列和相同,且尽可能大,就是暴力就能过,一个从前向后,一个从后向前,求和比较,相同记录下来,不同则分大于小于,左移右移。(附:如果没有long long 会wa10)

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
    long long maxn(long long a,long long s){
        if(a>s) return a;
        else return s;
    }
int main()
{
    int n;
    long long sum1=0,sum2=0;
    int num[200005];
    cin>>n;
    for(int i=0;i<n;i++) {
        cin>>num[i];
    }
    if(n==1){
        cout<<0<<endl;
        return 0;
    }
    int q=0,w=n-1;
    long long s=0;
    sum1+=num[q];
    sum2+=num[w];
    while(q<w){
        if(sum1<sum2) sum1+=num[++q];
        else if(sum1>sum2) sum2+=num[--w];
        else{
            s=maxn(sum1,s);
            sum1+=num[++q];
            sum2+=num[--w];
        }
    }
    cout<<s<<endl;
    return 0;
}

D题字符串操作,题意比较难懂,首先是给两个字符串,以及两种操作方式,即在同一字符串里可以前后交换(即swap(a【i】,a【n-i-1】)),以及两个字符串相同位置交换(swap(a【i】b【i】))。

,在操作前需要进行最少多少步对第一个字符串进行更改,能使得之后用两种操作方式变换使得两个字符串相等。

其实思路蛮容易想的,就是其实在两个字符串中用四个字符是相互关联的(a[i],a[n-i-1],b[i],b[n-1-i])

如果四个互不相同,则需要变换2次;

如果有两个相同,则看如果两个相同的都在第一个字符串上就需要变换两次,否则变换一次

如果有三个相同,则需要变换一次

如果有两两相同,则看第一个字符串的元素是否相同,如果相同就需要变换两次

附上代码

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <set>
using namespace std;

int main()
{
    int n,m=0;
    string a,b;
    cin>>n;
    cin>>a>>b;
    for(int i=0;i<n/2;i++){
        set<char> s;
        s.insert(a[i]);
        s.insert(a[n-i-1]);
        s.insert(b[i]);
        s.insert(b[n-i-1]);
        if(s.size()==4) m+=2;
        else if(s.size()==3){
            if(a[i]==a[n-i-1]) m+=2;
            else m+=1;
        }
        else if(s.size()==2){
            char c=*s.begin();
            int sum=0;
            if(a[i]==c) sum++;
            if(a[n-i-1]==c) sum++;
            if(b[i]==c) sum++;
            if(b[n-i-1]==c) sum++;
            if(sum==1||sum==3) m+=1;
        }
    }
    if(n%2==1){
        int j=n/2;
        if(a[j]!=b[j]) m++;
    }
    cout<<m<<endl;
    return 0;
}