/* 描述: 给定n个数字,求所有两两数字之差的绝对值的中位数。 可知,共有n*(n-1)/2=m个数字。 解析: 因为满足性质——假如对key可以找出>m/2个数字>=key,那么对于任意key‘, 有 key‘ <= key -> key‘亦满足性质 所以利用这个性质进行二分答案 ans是最终答案,也是最后一个满足性质的数字 对val,如果满足性质,那么val<=ans,否则val>ans 从0到最大值是范围。(left,right) test(val)——可以找出来>m/2个数字>=val(因为必须包含val自身,所以必然>m/2) ——假如可以,那么答案在集合[val,right)中 ——不可以,说明目前val过大了,答案在集合(left,val)中 test(val) range(c,1,n) { ans += n - (lower_bound(a,a+n,a[c]+val)-a); //找到第一个和目前差值>-=val的,计算总共有多少个这样的数字 } return ans > m/2; */ #include <cstdio> #include <iostream> #include <algorithm> #define range(i,a,b) for (int i=a;i<=b;i++) using namespace std; const int maxn = 100000; int a[maxn+1]; int n; int m; bool test(int val) { int ans(0); range(c,0,n-1) { ans += n - (lower_bound(a,a+n,a[c]+val) - a); } return ans > m; } void Work(int n) { m = (n-1)*n/4; range(i,0,n-1) { scanf("%d",&a[i]); } sort(a,a+n); int l(0),r(a[n-1]-a[0]);//注意r的初始化,直接为a[n-1]有点大 while(l+1<r)//必须如此,不然超时 { int mid = (l+r)>>1; if (test(mid)) { l = mid; } else { r = mid; } } if (test(r)) { cout<<r<<endl; } else { cout<<l<<endl; } } int main() { while(cin>>n) { Work(n); } return 0; }
时间: 2024-10-18 20:22:03