Median
Given?N?numbers,?X1,?X2, ... ,?XN, let us calculate the difference of every pair of numbers: ∣Xi?-?Xj∣ (1 ≤?i?<?j?≤?N). We can get?C(N,2)?differences through this work, and now your task is to find the median of the differences as quickly as you can!
Note in this problem, the median is defined as the?(m/2)-th? smallest number if?m,the amount of the differences, is even. For example, you have to find the third smallest one in the case of?m?= 6.
Input
The input consists of several test cases.
In each test case,?N?will be given in the first line. Then?N?numbers are given, representing?X1,?X2, ... ,?XN, (?Xi?≤ 1,000,000,000? 3 ≤ N ≤ 1,00,000 )
Output
For each test case, output the median in a separate line.
Sample Input
4 1 3 2 4 3 1 10 2Sample Output
1 8C++版本一
?
#include <iostream> #include <stdio.h> #include <string> #include <algorithm>using namespace std; int n,m; long long x[101000]; bool test(int mid){int cnt=0;for(int i=1;i<=n;i++){cnt+=n+1-(lower_bound(x+1,x+n+1,x[i]+mid)-x);}if(cnt>m)return true;return false; } int main() {while(~scanf("%d",&n)){for(int i=1;i<=n;i++){scanf("%I64d",&x[i]);}sort(x+1,x+n+1);int l=0;int r=x[n]-x[1];int ans=-1;m=n*(n-1)/4;while(l<=r){int mid=(l+r)>>1;if(test(mid)){ans=mid;l=mid+1;}elser=mid-1;}printf("%d\n",ans);}//cout << "Hello world!" << endl;return 0; }C++版本二
中文題意:
給N數字, X1, X2, … , XN,我們計算每對數字之間的差值:∣Xi - Xj∣ (1 ≤ i < j ≤ N). 我們能得到 C(N,2) 個差值,現在我們想得到這些差值之間的中位數。
如果一共有m個差值且m是偶數,那么我們規定中位數是第(m/2)小的差值。
輸入包含多測?
每個測試點中,第一行有一個NThen N 表示數字的數量。?
接下來一行由N個數字:X1, X2, … , XN?
( Xi ≤ 1,000,000,000 3 ≤ N ≤ 1,00,000 )
解題心得:
首先要知道的是n個數字可以得到C(N,2)個數字,那么要得到中位數,如果是偶數就要得到第n/2大的數字,如果是奇數就要得到第n/2+1個數字。
具體做法可以先將給出的數字排序,然后每次二分枚舉一個中位數(O(logn)),然后驗證比這個中位數小的數字有多少個,在驗證比這個中位數小的數字有多少個的時候可以選擇尺取法(具體實現看代碼,O(n)),這樣就在O(nlogn)的復雜度內完成。
?
?
總結