[百鍊智慧]hihoCoder挑戰賽36 #1838 : 鎕鎕鎕
阿新 • • 發佈:2018-12-11
#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; }