[CF798D]Mike and distribution_贪心

Mike and distribution

题目链接http://codeforces.com/problemset/problem/798/D

数据范围:略。


题解

太难了吧这个题.....

这种贪心根本就不咋会....接下来刷一段时间Atcoder看看好了.....

就是想到先把所有的对按照$a$排序。

然后刨除第一个外,相邻的两个分组。

第一个数单独一组,剩下的两两一组选$b$值较大的那对即可。

证明

首先,因为我们按照$a$排序,所以上一组的选取的$a$一定不比当前组剩下的$a$小,故此$a$数列满足条件。

紧接着,因为后面的每一组中,$b$值我们选择的是较大者,故此$b$数列满足条件。

证毕

代码

#include <bits/stdc++.h>

#define setIO(s) freopen(s".in", "r", stdin), freopen(s".out", "w", stdout) 

#define N 1000010 

using namespace std;

char *p1, *p2, buf[100000];

#define nc() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1 ++ ) 

int rd() {
    int x = 0;
    char c = nc();
    while (c < 48) {
        c = nc();
    }
    while (c > 47) {
        x = (((x << 2) + x) << 1) + (c ^ 48), c = nc();
    }
    return x;
}

struct Node {
    int x, y, id;
}a[N];

inline bool cmp(const Node &a, const Node &b) {
    return a.x > b.x;
}

int main() {
    // setIO("game");
    int n = rd();
    for (int i = 1; i <= n; i ++ ) {
        a[i].x = rd(), a[i].id = i;
    }
    for (int i = 1; i <= n; i ++ ) {
        a[i].y = rd();
    }
    sort(a + 1, a + n + 1, cmp);

    printf("%d
%d ", n / 2 + 1, a[1].id);

    for (int i = 2; i <= n; i += 2) {
        if (a[i].y > a[i + 1].y) {
            printf("%d ", a[i].id);
        }
        else {
            printf("%d ", a[i + 1].id);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/ShuraK/p/11721474.html