poj3579 Median

题意:给你100000个大小1000000000的数,他们任意组合差的绝对值的结果有组合数C(n,2)个,这个结果很大数组肯定存不下。问你这些差的绝对值的数中中位数是?
思路:第K大的数,当然是二分了。主要还是判断函数。对于每次x,直接二分原来序列里对于当前的数有多少个大于等于这个范围的数,求和,就可以知道这个x在差里面有多少个大于等于它的数,所以如果sum大于这个差序列里中位数以后数的个数才能说明,这个x至少满足或者有更大的x,反之,x则大了。

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int a[100000+10],n,m;
bool check(int x)
{
    int sum=0;
    for(int i=0;i<n;i++){
        sum+=n-(lower_bound(a,a+n,a[i]+x)-a);
    }
    return sum>(n*(n-1)/2-m);//这里我想了一会
}

int main()
{
    while(~scanf("%d",&n)){
        for(int i=0;i<n;i++) scanf("%d",&a[i]);
        sort(a,a+n);
        int l=0,r=a[n-1]-a[0];
        m=((n-1)*n/2+1)/2;//中位数的位置
        while(l<=r){
           int mid=(l+r)/2;
           if(check(mid)) l=mid+1;
           else r=mid-1;
        }
        printf("%d\n",l-1);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值