AtCoder Regular Contest 100 Equal Cut

Equal Cut

思路:

枚举中间那个分界点,然后两边找使得切割后差值最小的点,这个可以用双指针

代码:

#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;
}
原文地址:https://www.cnblogs.com/widsom/p/9279478.html