[codeforces23C]Oranges and Apples

time limit per test : 1.5 seconds
memory limit per test : 256 megabytes

分数:2500(补的有趣的老题)

In 2 N 1 2N - 1 boxes there are apples and oranges. Your task is to choose N N boxes so, that they will contain not less than half of all the apples and not less than half of all the oranges.

Input

The first input line contains one number T T — amount of tests. The description of each test starts with a natural number N N — amount of boxes. Each of the following 2 N 1 2N - 1 lines contains numbers a i a_i and o i o_i — amount of apples and oranges in the i i -th box ( 0 a i , o i 1 0 9 ) (0 ≤ a_i, o_i ≤ 10^9) . The sum of N in all the tests in the input doesn’t exceed 1 0 5 10^5 . All the input numbers are integer.
Output

For each test output two lines. In the first line output YES, if it’s possible to choose N N boxes, or NO otherwise. If the answer is positive output in the second line N N numbers — indexes of the chosen boxes. Boxes are numbered from 1 1 in the input order. Otherwise leave the second line empty. Separate the numbers with one space.

Examples
Input

2
2
10 15
5 7
20 18
1
0 0

Output

YES
1 3
YES
1

题意:
给定 2 n 1 2n-1 个篮子,第 i i 个篮子里面有 a i a_i 个苹果和 o i o_i 个橘子,询问能否从中取出 n n 个篮子,使得你得到的苹果数量是苹果总数的一半以上,并且橘子数量也是橘子总量的一半以上。

题解:
考虑构造一组解。
我们先把苹果按照从小到大排序,(下文中的位置为排完序的位置)然后取所有位置在 2 i 1 ( 1 < = i < = n ) 2i-1(1<=i<=n) 的篮子,如果这n个篮子里面的橘子数量不符合,那么就取所有位置为 2 i ( 1 < = i < = n 1 ) 2i(1<=i<=n-1) 的篮子,这样隔着取能保证取的苹果的数量一直大于等于苹果总量,最后再从没取的篮子里面找一个能让橘子和苹果的数量都是总量的一半以上的即可。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
struct Ds{
    int a,o,sit;
    void read(){
        scanf("%d%d",&a,&o);
    }
}p[200004];
inline bool dex(Ds A,Ds B){
    return A.a==B.a?A.o<B.o:A.a<B.a;
}
int n;
int w33ha(){
    scanf("%d",&n);
    ll sa=0,so=0;
    for(int i=1;i<=2*n-1;i++){
        p[i].read();
        p[i].sit=i;
        sa+=p[i].a;
        so+=p[i].o;
    }
    sort(p+1,p+2*n,dex);
    ll aa=0,ao=0;
    for(int i=1;i<=2*n-1;i+=2){
        aa+=p[i].a;
        ao+=p[i].o;
    }
    if(aa>=sa/2+(sa%2)&&ao>=so/2+(so%2)){
        puts("YES");
        for(int i=1;i<=2*n-1;i+=2){
            printf("%d ",p[i].sit);
        }
        puts("");
        return 0;
    }
    aa=sa-aa;
    ao=so-ao;
    for(int i=1;i<=2*n-1;i+=2){
        ll na=aa+p[i].a;
        ll no=ao+p[i].o;
        if(na>=sa/2+(sa%2)&&no>=so/2+(so%2)){
            puts("YES");
            for(int j=2;j<=2*n-1;j+=2){
                printf("%d ",p[j].sit);
            }
            printf("%d\n",p[i].sit);
            return 0;
        }
    }
    puts("NO");
    return 0;
}
int main(){
    int T;scanf("%d",&T);
    while(T--)w33ha();
    return 0;
}
发布了302 篇原创文章 · 获赞 19 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/dxyinme/article/details/100180358