poj3579 Median

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

  

原文地址:https://www.cnblogs.com/edmunds/p/13562472.html