Given N numbers, X1, X2, ... , XN, let us calculate the difference of every pair of numbers: ∣Xi - Xj∣ (1 ≤ i  j  N). We can get C(N,2) differences through this work, and now your task is to find the median of the differences as quickly as you can!

Note in this problem, the median is defined as the (m/2)-th  smallest number if m,the amount of the differences, is even. For example, you have to find the third smallest one in the case of = 6.

Input

The input consists of several test cases.
In each test case, N will be given in the first line. Then N numbers are given, representing X1, X2, ... , XN, ( Xi ≤ 1,000,000,000  3 ≤ N ≤ 1,00,000 )

Output

For each test case, output the median in a separate line.

Sample Input

4
1 3 2 4
3
1 10 2

Sample Output

1
8

C++版本一

 

#include <iostream>
#include <stdio.h>
#include <string>
#include <algorithm>

using namespace std;
int n,m;
long long x[101000];
bool test(int mid){

    int cnt=0;
    for(int i=1;i<=n;i++){
        cnt+=n+1-(lower_bound(x+1,x+n+1,x[i]+mid)-x);
    }
    if(cnt>m)
        return true;
    return false;
}
int main()
{
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;i++){
            scanf("%I64d",&x[i]);
        }
        sort(x+1,x+n+1);
        int l=0;
        int r=x[n]-x[1];
        int ans=-1;
        m=n*(n-1)/4;
        while(l<=r){
            int mid=(l+r)>>1;
            if(test(mid)){
                ans=mid;
                l=mid+1;
            }
            else
                r=mid-1;
        }
        printf("%d\n",ans);
    }
    //cout << "Hello world!" << endl;
    return 0;
}

C++版本二

中文题意:

给N数字, X1, X2, … , XN,我们计算每对数字之间的差值:∣Xi - Xj∣ (1 ≤ i < j ≤ N). 我们能得到 C(N,2) 个差值,现在我们想得到这些差值之间的中位数。

如果一共有m个差值且m是偶数,那么我们规定中位数是第(m/2)小的差值。

输入包含多测 
每个测试点中,第一行有一个NThen N 表示数字的数量。 
接下来一行由N个数字:X1, X2, … , XN 
( Xi ≤ 1,000,000,000 3 ≤ N ≤ 1,00,000 )

解题心得:

首先要知道的是n个数字可以得到C(N,2)个数字,那么要得到中位数,如果是偶数就要得到第n/2大的数字,如果是奇数就要得到第n/2+1个数字。
具体做法可以先将给出的数字排序,然后每次二分枚举一个中位数(O(logn)),然后验证比这个中位数小的数字有多少个,在验证比这个中位数小的数字有多少个的时候可以选择尺取法(具体实现看代码,O(n)),这样就在O(nlogn)的复杂度内完成。
 

#include <algorithm>
#include <stdio.h>
#include <cstring>
using namespace std;
const int maxn = 1e5+100;

int n,num[maxn];
long long tot;

void init() {
    tot = 0;
    tot = (long long)n*(n-1)/2;//差值的个数
    if(tot%2 == 0) {//中位数在第几个
        tot /=2;
    }
    else
        tot = tot/2 + 1;
    for(int i=0;i<n;i++) {
        scanf("%d",&num[i]);
    }
    sort(num,num+n);
}

bool checke(int va) {
    int t = 0;
    long long sum = 0;
    for(int i=0;i<n;i++) {
        while(t < n && num[t] - num[i] <= va)//尺取法看比va小的值有多少个
            t++;
        sum += t-i-1;
    }
    if(sum < tot)
        return true;
    return false;
}

int binary_search() {//每次枚举一个中位数的值
    int l,r;
    l = 0, r = 1e9+100;
    while(r - l > 1) {
        int mid = (l + r) >> 1;
        if(checke(mid))
            l = mid;
        else
            r = mid;
    }
    return r;
}

int main() {
    while(scanf("%d",&n ) != EOF) {
        init();
        int ans = binary_search();
        printf("%d\n",ans);
    }
    return 0;
}