首页 > 代码库 > poj 3579
poj 3579
/* 描述: 给定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;}
poj 3579
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。