CF23C Oranges and Apples

题面

先将所有盒子按苹果数排序,由于一共有奇数个盒子,此时取下标为奇数的盒子1、3、5、7...2n-1 一定可以使苹果满足条件(2n-1比2n-2大(或等于),2n-3比2*n-4大,...3比2大,最后还多下1,因此苹果树一定大于等于一半)

然后判断橘子数是否大于等于总数一半,如果大于,则直接选择这些下标为奇数的盒子

否则选择所有排序后下标为偶数的盒子和最后一个盒子(2*n-1),因为下标奇数盒子的橘子数小于一般,则下标偶数的橘子数总和一定多余一半,而苹果数也一定满足条件(证明同上,一一对应)

#include <bits/stdc++.h>
using namespace std;
#define int long long
inline void read (int &x) {
    char ch = getchar(); x = 0;
    while (!isdigit(ch)) ch = getchar();
    while (isdigit(ch)) x = x * 10 + ch - 48, ch = getchar();
} const int N = 2e5 + 10;
struct node {
    int a, b, k;
    bool operator < (const node &x) const { return a < x.a; }
} p[N]; vector<int> v;
signed main() {
    int T; read (T);
    while (T--) {
        int n, sa = 0, sb = 0, sc = 0; v.clear();
        read (n); n = n * 2 - 1;
        for (int i = 1; i <= n; ++i) p[i].k = i;
        for (int i = 1; i <= n; ++i)
            read (p[i].a), read (p[i].b), sa += p[i].a, sb += p[i].b;
        sort (p + 1, p + n + 1); puts ("YES");
        for (int i = 1; i <= n; i += 2) sc += p[i].b;
        if (sc * 2 >= sb) {
            for (int i = 1; i <= n; i += 2) v.push_back (p[i].k);
        } else {for (int i = 2; i <= n; i += 2) v.push_back (p[i].k); v.push_back (p[n].k);}
        sort (v.begin(), v.end());
        for (int i = 0; i < v.size(); ++i) printf ("%d ", v[i]); puts ("");
    } return 0;
}

原文地址:https://www.cnblogs.com/whx666/p/12670004.html