题目链接:https://vjudge.net/problem/POJ-3579
题意:给定n个数两两作差,求这些差的中位数
m个数,中位数就是第(m/2)小的数。考虑二分答案,判断有多少个<=该答案即可。这儿先把原数组先排序,然后用upper_bound统计(例如答案为m,则对于a[p],可以找到a[q]使得差<=m的个数即为upper_bound(x+1,x+n+1,x[p]+m)-(x+1)-p),见代码)
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
int n,i,j,l,r,m,x[100010];
ll tot;
bool check(int m){
int p=1; ll cnt=0;
while (p<=n){
int q=(int)(upper_bound(x+1,x+n+1,x[p]+m)-(x+1));
cnt+=q-p; p++;
}
return cnt>=tot;
}
int main(){
while (~scanf("%d",&n)){
for (i=1;i<=n;i++) scanf("%d",&x[i]);
sort(x+1,x+n+1);
l=0; r=1e9;
tot=((n*(n-1))%4==0)?n*(n-1)/4:n*(n-1)/4+1;
while (r-l>1){
int m=(l+r)/2;
if (check(m)) r=m;else l=m;
}
printf("%d
",r);
}
return 0;
}