zoukankan      html  css  js  c++  java
  • POJ 3579 median 二分搜索,中位数 难度:3

    Median
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 3866   Accepted: 1130

    Description

    Given N numbers, X1X2, ... , 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 X1X2, ... , XN, ( X≤ 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
    思路: 一眼可知把原数列a排列一遍的时间还是有的,但是要想得到两两之差然后归并则T,M都超,计数范围也太大了,
    把a排序之后两两相减,得到相邻差数组b,那么b就可以构成所有需要的差了,
    那么现在假设有个差delta,使得a[i]+delta<=a[j],a[i]+delta>a[j-1],那么delta一定大于a[j-1]-a[i],a[j-2]-a[i]....delta一定小于等于a[j]-a[i],a[j+1]-a[i],
    使用low_bound可以在logn时间内求出j,nlogn时间就可以求出所有比delta大的差的个数,
    这时就可以判断是否delta算是差的中位数.
    那么直接二分差即可,总时间n*logn*logn,5*1e7-1e8的数量级,可以跑过
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn=1e5+5;
    int a[maxn];
    long long halfh,h;
    int n;
    bool judge(int mid){
        long long cnt=0;
        for(int i=0;i<n;i++){
            cnt+=a+n-lower_bound(a+i,a+n,a[i]+mid);
        }
        return cnt>halfh;
    }
    int main(){
        while(scanf("%d",&n)==1){
            h=n*(n-1)/2;halfh=h/2;
            for(int i=0;i<n;i++){scanf("%d",a+i);}
            sort(a,a+ n);
            int l=0,r=a[n-1],mid;
            while(r-l>1){
                mid=r+l>>1;
                if(judge(mid)){
                    l=mid;
                }
                else r=mid;
            }
            printf("%d\n",l);
        }
    }
    

      

     
  • 相关阅读:
    strcpy和memcpy的区别《转载》
    C++数组引用
    关于C++中继承、重载、掩盖 《转载》
    对于js原型和原型链继承的简单理解(第三种,复制继承)
    对于js原型和原型链继承的简单理解(第二种,对象冒充)
    腾讯的一道js面试题(原型)
    面试题,自己写写dome总是好的
    对于js原型和原型链继承的简单理解(第一种,原型链继承)
    html+css布局小练习w3cfuns
    C#泛型列表List<T>基本用法总结
  • 原文地址:https://www.cnblogs.com/xuesu/p/3969503.html
Copyright © 2011-2022 走看看