Median POJ3579
投稿日: 更新日:
問題:http://poj.org/problem?id=3579
問題
個の数が与えられます。この中から2つ選びその絶対値の差を求めます。全部で個あるのでその中央値を求めてください。もし、偶数個の場合は番目の数を求めてください
解法
を満たす組み合わせは何個あるかで2分探索をします。
あらかじめ数列をソートしておきます。を固定したとき、が成り立つを2分探索で求めれば個数がすぐに求まります。実装ではlower_bound
を使用しています。
実装
cin
、cout
を使うとTLEしました。scanf
、printf
を使って922MSだったのでギリギリです。厳しい。。。。
#include <stdio.h>
#include <vector>
#include <algorithm>
using namespace std;
int main(){
int n;
while(scanf("%d", &n) != EOF){
vector<int> a(n);
for(int i = 0;i < n; ++i){
scanf("%d", &a[i]);
}
sort(a.begin(), a.end());
long long med = 1LL*n*(n-1)/4+1;
int ng = 1e9+10, ok = 0;
while(ng - ok > 1){
int mid = (ok+ng)/2;
long long count = 0;
for(int i = 0;i < n; ++i){
count += a.end() - lower_bound(a.begin()+i+1, a.end(), a[i]+mid);
}
if(count >= med){
ok = mid;
}else{
ng = mid;
}
}
printf("%d\n", ok);
}
return 0;
}