题解:P12605 求和

· · 题解

题意:给定一个序列,可以进行若干次操作。每次操作选择两个不同的下标 ij,将 a_i1a_j1,最后要让序列的前缀和之和等于后缀和之和,求最小的操作次数。如果无法实现,输出 -1

假设前缀和之和为 S,后缀和之和为 T,题目就可以这么做:

代码:

#include<bits/stdc++.h>
using namespace std;
int n, a[1000005];
long long s, t, p, s1;//p 是前缀和的累加器,s1 是后缀和的累加器,s 是前缀和之和,t 是后缀和之和。 
int main() {
    cin>> n;
    for(int i=0;i<n;i++) cin>> a[i];
    if(n==1) {
        cout<<0;
        return 0;
    }//特判,n 为 1,就说明 S 和 T 已经相同了,所以是操作 0 次。
    for(int i=0;i<n;i++) {
        p+=a[i];
        s+=p;
    }//计算前缀和。
    for(int i=n-1;i>=0;i--) {
        s1+=a[i];
        t+=s1;
    }//计算后缀和。
    if((s-t)%2!=0) cout<<-1;// S-T 为奇数,但每次操作变化的数为偶数,所以肯定无解。
    else cout<<(abs(s-t)+(2*n-2)-1)/(2*n-2);
    return 0;
}