H - Median

H - Median
Given N numbers, X 1, X 2, ... , 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 m = 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

        之前一直都是在怕超时,后来竟然没有超,还是特别开心的啦!
        思路:我在这里是用0~(ai[n-1]-ai[0])之间的差值进行的二分的方法,之后用了一个双重的循环,来判断小于m的个数,                     方法还是比较简单易懂的,相信可以理解的!
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
using namespace std;
long long n,m;
int ai[100005];
int fun(int mid)
{
    int sum=0,r=1;
    for(int i=0;i<n;i++)
    {
        while(ai[r]-ai[i]<=mid&&r<n) r++;
        sum+=r-i-1;//减1 是因为上面多加了一个 1;
    }
    if(sum>=m) return 1;
    return 0;
}
int main()
{
    while(scanf("%lld",&n)==1)
    {
        for(int i=0;i<n;i++)
            scanf("%d",&ai[i]);
        m=n*(n-1)/2;
        if(m%2==0) m=m/2;
        else    m=(m+1)/2;
        sort(ai,ai+n);
        int q=0,w=ai[n-1]-ai[0],mid;
        while(q<=w)
        {
            mid=(q+w)/2;
            if(fun(mid))
                w=mid-1;/*为什么是把 mid-1 赋值给 w 呢?是因为,如果满足了那个 m 的话,说明小于 这个差是比较多的,所以                                        二分是要把这个范围缩小,变成 [q,mid-1]*/
            else
                q=mid+1;
        }
        printf("%d\n",w+1);
    }
}

猜你喜欢

转载自blog.csdn.net/hnust_lec/article/details/79341015