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;
}