• POJ3579题解 二分搜索+调用函数


    题目链接:http://poj.org/problem?id=3579

    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

    题目意思:在n个数字中找出两两差值(绝对值)的中位数。

    首先要了解一下lower_bound()这个函数,它是一个能够找出递增序列中第一个大于等于某个数的函数,它和upper_bound()相对应。不知道的戳这里:https://www.cnblogs.com/Tang-tangt/p/9291018.html

    解题思路:首先我们要知道,n个数存在n*(n-1)/2个差值(组合数),而这个数量级就已经达到了十次方,所以我们无法直接存差值。正确的解法是二分列举差值,如果超过这个差值的组合数超过总组合数的一半,则中位数必定比该差值更大,反之则更小。

    代码如下:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    const int maxn = 1e5+5;
    int a[maxn];
    int n, m;
    bool test(int val)
    {
        int cnt=0;
        for(int i=0;i<n;i++)
        {
            cnt+=n-(lower_bound(a,a+n,a[i]+val)-a);//a[i]对应的(即与a[i]形成差值)原序列中比a[i]+val大的元素个数(也即是部分组合数) 
        }
        return cnt>m;//如果大于差值val的对应的组合总数超过了一半 
    }
    int main()
    {
        while(scanf("%d",&n)!=EOF)
        {
             m=n*(n-1)/4;
             for(int i=0;i<n;i++)
                 scanf("%d",&a[i]);
             sort(a,a+n);
             int l=0,r=a[n-1]-a[0];
             while(r-l>1)
             {
                 int mid=(l+r)>>1;
                 if(test(mid))l=mid;//如果val对应差值组合数超过一半则所有差值的中位数必然比mid更大 
                 else r=mid;
             }
             printf("%d
    ",l);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    CodeForces 242E二维线段树
    树形DP
    014 国际化
    013 属性文件
    012 BeanPostProcessor
    011 aware
    010 依赖注入
    009 IOC--初始化和销毁
    008 IOC--Bean的作用域
    007 IOC---Resource
  • 原文地址:https://www.cnblogs.com/Mingusu/p/11708871.html
Copyright © 2020-2023  润新知