1. 程式人生 > >[百鍊智慧]hihoCoder挑戰賽36 #1838 : 鎕鎕鎕

[百鍊智慧]hihoCoder挑戰賽36 #1838 : 鎕鎕鎕

#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

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