zoukankan      html  css  js  c++  java
  • poj3579 二分搜索+二分查找

    Median
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 5468   Accepted: 1762

    Description

    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 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
    题目大意:给你n个数,任意两个数之间的差共有m=(n-1)*n/2种然后让你输出这些数中间的那一个,规则为
    若m为奇数,中间的那一个为第(m+1)/2小的数,若m为为偶数,中间那个数指的是第m/2小的数。
    思路分析:看了一下数据范围,如果用最正常最简单的做法,复杂度O(n^2),肯定会超时,因此需要采用高效率的
    二分算法,因为a[i]-a[j]是取了绝对值的,因此就相当于是大的减小的,因此可以将数组a[n]先sort排序,然后
    根据差值确定二分范围,我确定的是0~a[n-1]-a[0],然后开始二分搜索,而check函数则主要是统计比a[i]+d小的
    数有多少个,如果>=(m+1)/2就return true else return false,而在统计的过程中如果用传统的顺序查找肯
    定也会到致超时,所以应该使用高效率的二分查找,我直接用了upper_bound函数,统计的时候注意upper_bound-a
    是所有<=a[i]+x的数组元素的个数,应该减去所有<=a[i]的元素(共i+1个)
    代码:
    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    int a[100000+5];
    int n;
    int temp;
    bool check(int x)
    {
        int cnt = 0;
        for(int i=0; i<n; i++)
        {
           int t=upper_bound(a,a+n,a[i]+x)-a;//比a[i]+x小的元素的个数
           cnt+=(t-i-1);//排除a[i]之前的那些元素,共有i+1;
        }
        if(cnt>=temp) return true; 
            else return false;
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
             for(int i=0;i<n;i++)
                scanf("%d",&a[i]);
             sort(a,a+n);
             int m=n*(n-1)/2;
             temp=(m+1)/2;
             int l=0,r=a[n-1]-a[0];
             int ans;
             while(l<=r)//二分搜索
             {
                 int mid=(l+r)>>1;
                 if(check(mid))
                  ans=mid,r=mid-1;
                 else l=mid+1;
             }
             printf("%d ",ans);
        }
        return 0;
    }
  • 相关阅读:
    1.两数之和
    [Udemy] ES 7 and Elastic Stack
    [Udemy] ES 7 and Elastic Stack
    Common Linux Commands 日常工作常用Linux命令
    ELK 学习
    web 3d 技术预研及数据可视化技术
    AWS Cloud Practioner 官方课程笔记
    怎么用 pytorch 查看 GPU 信息
    ECG 项目预研
    怎么查看keras 或者 tensorflow 正在使用的GPU
  • 原文地址:https://www.cnblogs.com/xuejianye/p/5525747.html
Copyright © 2011-2022 走看看