Educational Codeforces Round 6 D. Professor GukiZ and Two Arrays(二分 | two pointers)

题意:

N2×103,0k22,使|sumasumb|

分析:

k,,k=0k=1
k=2,2C2n
2ai,bj,asuma=sumaai+bj,bsumb=sumb+aibj
dif=sumasumb=sumasumb+2(ai+bj)
dif=sumasumb,dif=dif+2(ai+bj)
ai,bj=(dif2ai)/2,,.5
bj,
dif,,2

代码:

//
//  Created by TaoSama on 2016-01-22
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
#define pr(x) cout << #x << " = " << x << "  "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;

typedef long long LL;

int n, m;
int a[N], b[N], ans[5];

void update(LL& cur, LL& minv, int a1, int a2, int a3, int a4) {
    if(cur < minv) {
        minv = cur;
        ans[1] = a1;
        ans[2] = a2;
        ans[3] = a3;
        ans[4] = a4;
    }
}

int main() {
#ifdef LOCAL
    freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);
//  freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);
#endif
//    ios_base::sync_with_stdio(0);

    while(scanf("%d", &n) == 1) {
        LL suma = 0, sumb = 0;
        for(int i = 1; i <= n; ++i) scanf("%d", a + i), suma += a[i];
        scanf("%d", &m);
        for(int i = 1; i <= m; ++i) scanf("%d", b + i), sumb += b[i];

        LL dif = suma - sumb, minv = abs(dif);
        for(int i = 1; i <= 4; ++i) ans[i] = -1;
        for(int i = 1; i <= n; ++i) {
            for(int j = 1; j <= m; ++j) {
                LL cur = abs(dif + 2LL * (-a[i] + b[j]));
                update(cur, minv, i, j, -1, -1);
            }
        }

        vector<pair<LL, pair<int, int> > > va, vb;
        for(int i = 1; i <= n; ++i)
            for(int j = i + 1; j <= n; ++j)
                va.push_back({a[i] + a[j], {i, j}});
        for(int i = 1; i <= m; ++i)
            for(int j = i + 1; j <= m; ++j)
                vb.push_back({b[i] + b[j], {i, j}});
        sort(vb.begin(), vb.end());

        for(auto &x : va) {
            LL cur = dif - 2 * x.first;
            auto iter = lower_bound(vb.begin(), vb.end(),
                                    make_pair(-cur / 2, make_pair(-1, -1)));
            if(iter != vb.end()) {
                LL tmp = abs(cur + 2 * iter->first);
                update(tmp, minv, x.second.first, x.second.second, iter->second.first,
                       iter->second.second);
            }
            if(iter != vb.begin()) {
                --iter;
                LL tmp = abs(cur + 2 * iter->first);
                update(tmp, minv, x.second.first, x.second.second, iter->second.first,
                       iter->second.second);
            }
        }

        if(ans[1] == -1) printf("%I64d\n0\n", minv);
        else if(ans[3] == -1) {
            printf("%I64d\n1\n", minv);
            printf("%d %d\n", ans[1], ans[2]);
        } else {
            printf("%I64d\n2\n", minv);
            printf("%d %d\n", ans[1], ans[3]);
            printf("%d %d\n", ans[2], ans[4]);
        }
    }
    return 0;
}

k=2,使2,使two pointers,log
0,2two pointers,bj,dif
<0,

代码:

//
//  Created by TaoSama on 2016-01-22
//  Copyright (c) 2015 TaoSama. All rights reserved.
//
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <algorithm>
#include <cctype>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
#include <set>
#include <vector>

using namespace std;
#define pr(x) cout << #x << " = " << x << "  "
#define prln(x) cout << #x << " = " << x << endl
const int N = 1e5 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;

typedef long long LL;

int n, m;
int a[N], b[N];
typedef pair<int, int> P;
P ans[3];

void update(LL& cur, LL& minv, P a1, P a2) {
    if(cur < minv) {
        minv = cur;
        ans[1] = a1;
        ans[2] = a2;
    }
}

int main() {
#ifdef LOCAL
    freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);
//  freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);
#endif
//    ios_base::sync_with_stdio(0);

    while(scanf("%d", &n) == 1) {
        LL suma = 0, sumb = 0;
        for(int i = 1; i <= n; ++i) scanf("%d", a + i), suma += a[i];
        scanf("%d", &m);
        for(int i = 1; i <= m; ++i) scanf("%d", b + i), sumb += b[i];

        LL dif = suma - sumb, minv = abs(dif);
        for(int i = 1; i <= 2; ++i) ans[i] = { -1, -1};
        for(int i = 1; i <= n; ++i) {
            for(int j = 1; j <= m; ++j) {
                LL cur = abs(dif + 2LL * (-a[i] + b[j]));
                update(cur, minv, {i, j}, { -1, -1});
            }
        }

        vector<pair<LL, pair<int, int> > > va, vb;
        for(int i = 1; i <= n; ++i)
            for(int j = i + 1; j <= n; ++j)
                va.push_back({a[i] + a[j], {i, j}});
        for(int i = 1; i <= m; ++i)
            for(int j = i + 1; j <= m; ++j)
                vb.push_back({b[i] + b[j], {i, j}});
        sort(va.begin(), va.end());
        sort(vb.begin(), vb.end());

        int j = 0;
        for(int i = 0; i < va.size(); ++i) {
            while(j < vb.size() && dif + 2 * (-va[i].first + vb[j].first) < 0) ++j;
            if(j < vb.size()) {
                LL cur = abs(dif + 2 * (-va[i].first + vb[j].first));
                update(cur, minv, va[i].second, vb[j].second);
            }
            if(j - 1 >= 0) {
                LL cur = abs(dif + 2 * (-va[i].first + 0LL + vb[j - 1].first));
                update(cur, minv, va[i].second, vb[j - 1].second);
            }
        }

        if(ans[1].first == -1) printf("%I64d\n0\n", minv);
        else if(ans[2].first == -1) {
            printf("%I64d\n1\n", minv);
            printf("%d %d\n", ans[1].first, ans[1].second);
        } else {
            printf("%I64d\n2\n", minv);
            printf("%d %d\n", ans[1].first, ans[2].first);
            printf("%d %d\n", ans[1].second, ans[2].second);
        }
    }
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值