题目描述
两次二分。
先二分差值,l=0,r为最大值和最小值之差。
check函数计算,当前mid作为中值条件下,用lower_bound来计算得出大于mid的差值个数。
如果差值个数多于Cn2的一半,则返回true,否则返回false。
C++ 代码
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<string>
#include<cmath>
using namespace std;
typedef long long LL;
const int N=1e5+10;
LL n,m;
LL a[N];
bool check(LL ans)
{
int cnt=0;
for(int i=1;i<=n;i++)
{
cnt+=n-(lower_bound(a+1,a+n+1,a[i]+ans)-a-1);
}
if(cnt>m) return true;
else return false;
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
sort(a+1,a+1+n);
m=n*(n-1)/4;
LL l=0,r=a[n]-a[1];
LL mid,ans;
while(l<r)
{
mid=(l+r+1)>>1;
if(check(mid)) l=mid;
else r=mid-1;
}
printf("%d\n",l);
}
return 0;
}