题目链接: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; }