POJ 3579 Median 二分+思维

Posted alking1001

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 3579 Median 二分+思维相关的知识,希望对你有一定的参考价值。

POJ 3579 Median 二分+思维

题意

给你一些数,然后求这些数相互之间差的绝对值,然后绝对值排序,找到中间那个数。

解题思路

我反正一直开始是没有想到这个题竟然可以用二分来做。━━( ̄ー ̄*|||━━.

二分枚举答案,假设枚举值为mid,然后就是在排好序的序列中对每一个num[i]找到在i之后,有多少个大于num[i]+mid的数的个数(数列里的值比num[i]+mid大,说明该值与num[i]作差形成的新数列里的数比中位数mid大),用lower_bound计算所有差值比mid大于等于的组合个数。如果个数之和小于新数列个数的一半,则说明mid大了。

代码实现

#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<stack>
#include<queue>
#include<map>
typedef long long ll;
using namespace std;
const double esp=1e-6;
const int inf=0x3f3f3f3f;
const int MAXN=1e5+7;
ll num[MAXN], n, m;
ll solve(ll value)
{
    ll cnt=0;
    for(int i=0; i<n; i++)
        cnt += num+n - lower_bound(num, num+n, num[i]+value);
    return cnt;
}
int main()
{
    while(scanf("%d",&n)!=EOF)
    {
        for(int i=0; i<n; i++)
            scanf("%d", &num[i]);
        sort(num, num+n);
        m = n*(n-1)/2;
        int lt=0, rt=num[n-1]+1, ans=0;
        while(lt<rt)
        {
            int mid=lt+(rt-lt)/2;
            //注意这里是和m/2进行比较,没有分奇偶
            //这是因为,m/2代表的是差的绝对值数列(排序后)在答案右边的个数,奇偶一样
            //n=4的时候,1 2 3 4,差值序列:1 1 1 2 2 3,m=6,m/2=3表示在答案右边(包括答案)的个数,也就是2 2 3。
            //n=3时,1 10 2,差值序列:1 8 9,m=3,m/2=1,也就是9,这一个数。
            if(solve(mid) > m/2 ) 
                lt=mid+1;
            else rt=mid;
        }
        printf("%d
", lt-1);
    }
    return 0;
}

以上是关于POJ 3579 Median 二分+思维的主要内容,如果未能解决你的问题,请参考以下文章

POJ-3579 Median---二分第k大(二分套二分)

POJ 3579 Median(二分答案+Two pointers)

POJ - 3579 Median(二分)

POJ 3579 Median

POJ3579 Median

POJ 3579 - Median 题解