简要题意:
给你一个序列长度为 n,让你把它分成4份,设每一段的和为 s1,s2,s3,s4,让你求出 max(s1,s2,s3,s4)−min(s1,s2,s3,s4) 的最小值。
4≤n≤106,ai≤109
连样例都没过
样例输入:
7
20 22 3 12 20220312 2022 312
输出:
20220255
代码,主要就是前缀和+双指针+贪心,,,
#include<bits/stdc++.h>
using namespace std;
long long n,tmp,s[1000001],opt = 1e18;
struct node{
long long zx,zd;
}prea,preb;
int better(int a,int b,int c,node &tt){
tt.zx = min(s[b]-s[c-1],s[c-1]-s[a-1]);
tt.zd = max(s[b]-s[c-1],s[c-1]-s[a-1]);
node cur;
cur.zd = max(s[b]-s[c],s[c]-s[a-1]);
cur.zx = min(s[b]-s[c],s[c]-s[a-1]);
if(cur.zd-cur.zx<tt.zd-tt.zx){
tt = cur;
return 1;
}
return 0;
}
int main(){
cin>>n;
for(int i = 1;i<=n;i++) {
cin>>tmp;
s[i] = s[i-1]+tmp;
}
int a = 1,b = 2,c = 3;
preb.zd = max(s[n]-s[c],s[c]-s[b]);
preb.zx = min(s[n]-s[c],s[c]-s[b]);
prea.zd = max(s[1],s[2]-s[1]);
prea.zx = min(s[1],s[2]-s[1]);
for(c = 4;c<n;)
if(better(b+1,n,c,preb)) c++;
else break;
opt = max(prea.zd,preb.zd)-min(prea.zx,preb.zx);
for(int b = 3;b<=n-2;b++){
if(better(1,b,a+1,prea)) a++;
if(better(b+1,n,c+1,preb)) c++;
opt = min(max(prea.zd,preb.zd)-min(prea.zx,preb.zx),opt);
}
cout<<opt;
return 0;
}