CodeForces 620D Professor GukiZ and Two Arrays 双指针

Professor GukiZ and Two Arrays

题解:

将a数组都sort一遍之后, b数组也sort一遍之后。

可以观察得到 对于每一个ai来说, 整个数组bi是一个V型的。

并且对于ai+1的最优解一定是在ai的右边。

然后我们将a数组 和 b数组枚举一遍。

然后再将a数组22组合, b数组22组合之后, 再枚举一遍。

代码:

#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define LL long long
#define ULL unsigned LL
#define fi first
#define se second
#define pb push_back
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define lch(x) tr[x].son[0]
#define rch(x) tr[x].son[1]
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))
typedef pair<int,int> pll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const LL _INF = 0xc0c0c0c0c0c0c0c0;
const LL mod =  (int)1e9+7;
const int N = 4e6 + 100;
int a[N], b[N];
struct Node{
    int v, l, r;
    bool operator<(const Node & t) const{
        return v < t.v;
    }
}A[N], B[N];
LL ans;
pll ansa, ansb;
LL suma = 0, sumb = 0;
int f;
LL cal(int i, int j){
    LL tsuma = suma - A[i].v + B[j].v;
    LL tsumb = sumb - B[j].v + A[i].v;
    return abs(tsuma - tsumb);
}
void Find(int n, int m){
    if(!n || !m) return ;
    sort(A+1, A+1+n); sort(B+1, B+1+m);
    for(int i = 1, j = 1; i <= n; ++i){
        while((j+1) <= m && cal(i,j) >= cal(i,j+1)) ++j;
        if(ans > cal(i,j)){
            ans = cal(i, j);
            ansa = pll(A[i].l, B[j].l);
            ansb = pll(A[i].r, B[j].r);
        }
    }
}
int main(){
    int n, m;
    scanf("%d", &n);
    f += (n==1000);
    for(int i = 1; i <= n; ++i){
        scanf("%d", &a[i]);
        A[i] = {a[i], i, 0};
        suma += a[i];
    }
    scanf("%d", &m);
    for(int i = 1; i <= m; ++i){
        scanf("%d", &b[i]);
        B[i] = {b[i], i, 0};
        sumb += b[i];
    }
    ans = abs(suma - sumb); ansa = ansb = {0, 0};
    Find(n, m);
    int atot = 0, btot = 0;
    for(int i = 1; i <= n; ++i){
        for(int j = i+1; j <= n; ++j){
            A[++atot] = {a[i]+a[j], i, j};
        }
    }
    for(int i = 1; i <= m; ++i){
        for(int j = i+1; j <= m; ++j){
            B[++btot] = {b[i]+b[j], i, j};
        }
    }
    Find(atot, btot);
    printf("%lld
", ans);
    if(ansa.fi == 0){
        puts("0");
    }
    else if(ansb.se == 0){
        puts("1");
        printf("%d %d
", ansa.fi, ansa.se);
    }
    else {
        puts("2");
        printf("%d %d
", ansa.fi, ansa.se);
        printf("%d %d
", ansb.fi, ansb.se);
    }
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/MingSD/p/10916741.html