#1838 : 鎕鎕鎕
时间限制:22000ms
单点时限:1000ms
内存限制:256MB
描述
鎕鎕有 2n + 1 张卡片,每张卡片上都有两个数字,第 i 张卡片上的两个数字分别是 Ai 与 Bi。
现在鎕鎕要从所有卡片中选出恰好 n + 1 张卡片,然后计算他选出的所有卡片中 Ai 的和与 Bi 的和。他的目的是要使他选出的卡片的Ai 的和与 Bi 的和,都要分别大于剩下 n 张没选的卡片的 Ai 的和与 Bi 的和。
鎕鎕最近沉迷于玩 Switch,所以他希望你能帮他解决这个问题。
输入
输入第一行是一个整数 n,意义如以上所示。
接下来有 2n + 1 行,每行为两个正整数,第 i 行的两个正整数分别代表 Ai 和 Bi。
数据保证 1 ≤ n ≤ 100000,1 ≤ Ai, Bi ≤ 109。
输出
如果无法选出 n + 1 张卡片满足鎕鎕的要求,输出一个数 -1。否则输出 n + 1 行,每行有一个正整数,表示选出的卡片编号(从 1 开始)。如果有多解,输出任意一组解均可。
样例输入
2 4 2 9 4 5 3 7 5 8 1
样例输出
3 4 2
官方题解:https://media.hihocoder.com/contests/challenge36/challenge36_solution.pdf
Orz 昂神学长
先把所有卡片按照Ai排序。
样例:
4 5 7 8 9
2 3 5 1 4
每两个卡片中选Bi较大的即可,最后剩下一张Ai最大的卡片。
以上是官方题解。
这里说一下为什么是对的。
我们看最坏情况,就是每一次选择Bi大的都是Ai小的那一个,但是我们注意到对于某一组的Ai大的卡片,下一组的Ai小的一定比其大,倒数第二组的Ai大的卡片一定比最后一组(单独一张卡的那一组)的Ai小。
证明完毕。
代码:
#include<bits/stdc++.h>
using namespace std;
struct node
{
int a,b,num;
}x[200010];
bool cmp(node aa,node bb)
{
if(aa.a==bb.a)return aa.b<bb.b;
return aa.a<bb.a;
}
int main()
{
int n,i,N;
scanf("%d",&n);
N=2*n+1;
for(i=1;i<=N;i++)
{
scanf("%d %d",&x[i].a,&x[i].b);x[i].num=i;
}
sort(x+1,x+N+1,cmp);
for(i=1;i<=N;i+=2)
{
if(x[i].b>x[i+1].b)printf("%d\n",x[i].num);
else printf("%d\n",x[i+1].num);
}
return 0;
}