Median POJ - 3579 (二分 有點玄學)
阿新 • • 發佈:2018-10-31
題意:給一串數,共n*(n-1)/2個差值,求差值從大到小排序的中值,偶數向下取.
題解:使用二分答案,然後可以先把數排序,然後下界0,上界a[n]-a[1],二分假定中值d,如果所有差值中大於等於d的小於等於N/2,說明d太大了.判斷d是否可行時如果列舉差值就太慢了,可以對於每一個數x,找所有滿足xi>=x+d(xi>x)的xi的個數,這裡還是用二分,直接lower_bound即可.,但是我這個二分雖然過了,但是答案要減一才可以,玄了。
附上程式碼:
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; const int maxn=1e5+50; int n,N; int a[maxn]; bool C(int d) { int cnt=0; for(int i=0;i<n-1;i++){ cnt+=a+n-(lower_bound(a+i+1,a+n,a[i]+d)); } return cnt<=N/2; } void solve() { sort(a,a+n); int lb=-1,ub=a[n-1]-a[0]+1; while(ub-lb>1){ int mid=(lb+ub)>>1; if(C(mid)){ ub=mid; }else{ lb=mid; } } printf("%d\n",ub-1); } int main() { while(scanf("%d",&n)!=EOF){ N=n*(n-1)/2; for(int i=0;i<n;i++){ scanf("%d",&a[i]); } solve(); } return 0; }