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