站外题求调。
  • 板块学术版
  • 楼主XKqwq
  • 当前回复14
  • 已保存回复14
  • 发布时间2022/10/4 20:56
  • 上次更新2023/10/27 08:47:37
查看原帖
站外题求调。
572558
XKqwq楼主2022/10/4 20:56

简要题意:

给你一个序列长度为 nn,让你把它分成4份,设每一段的和为 s1,s2,s3,s4s1,s2,s3,s4,让你求出 max(s1,s2,s3,s4)min(s1,s2,s3,s4)\operatorname{max}(s1,s2,s3,s4)- \operatorname{min}(s1,s2,s3,s4) 的最小值。

4n106,ai1094\le n\le10^6,a_i\le 10^9


连样例都没过

样例输入:

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;
}

2022/10/4 20:56
加载中...