思路:
枚举中间那个分界点,然后两边找使得切割后差值最小的点,这个可以用双指针
代码:
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long #define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define piii pair<int,pii> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 2e5 + 5; const LL INF = 0x3f3f3f3f3f3f3f3f; int a[N]; LL sum[N]; LL get_s(int l, int r) { if(l > r) return INF; return sum[r] - sum[l-1]; } int main() { int n; scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &a[i]); for (int i = 1; i <= n; i++) sum[i] = sum[i-1] + a[i]; LL ans = INF; int l1 =1, l2 = 3; for (int i = 2; i < n-1; i++) { while(l1+1 < i && abs(get_s(1, l1) - get_s(l1+1, i)) >= abs(get_s(1, l1+1) - get_s(l1+2, i))) l1++; l2 = max(l2, i+1); while(l2+1 < n && abs(get_s(i+1, l2) - get_s(l2+1, n)) >= abs(get_s(i+1, l2+1) - get_s(l2+2, n))) l2++; LL mn = INF, mx = 0; mn = min(mn, get_s(1, l1)); mx = max(mx, get_s(1, l1)); mn = min(mn, get_s(l1+1, i)); mx = max(mx, get_s(l1+1, i)); mn = min(mn, get_s(i+1, l2)); mx = max(mx, get_s(i+1, l2)); mn = min(mn, get_s(l2+1, n)); mx = max(mx, get_s(l2+1, n)); ans = min(ans, mx - mn); } printf("%lld ", ans); return 0; }