中國大學MOOC—陸軍工程大學資料結構MOOC習題集(2018秋)7-3 中位數
阿新 • • 發佈:2018-11-13
7-3 兩個有序序列的中位數 (25 分)已知有兩個等長的非降序序列S1, S2, 設計函式求S1與S2並集的中位數。有序序列A0,A1,⋯,AN−1的中位數指A(N−1)/2的值,即第⌊(N+1)/2⌋個數(A0為第1個數)。
輸入格式:
輸入分三行。第一行給出序列的公共長度N(0<N≤100000),隨後每行輸入一個序列的資訊,即N個非降序排列的整數。數字用空格間隔。
輸出格式:
在一行中輸出兩個輸入序列的並集序列的中位數。
輸入樣例1:
5
1 3 5 7 9
2 3 4 5 6
輸出樣例1:
4
輸入樣例2:
6
-100 -10 1 1 1 1
-50 0 2 3 4 5
輸出樣例2:
1
解題思路:
(1)將兩個序列合併成一個序列,然後進行排序,排序之後取出新序列的中位數。
(2)中位數演算法:首先將兩個序列分別排序變成兩個升序序列,分別求兩個升序序列A、B的中位數,設為a和b。
若a=b,則a或b即為所求的中位數;
否則,捨棄a、b中較小者所在序列之較小一半,同時捨棄較大者所在序列之較大一半,要求兩次捨棄的元素個數相同。當A長度位奇數時,左半邊=右半邊,直接捨棄即可。當A長度位為偶數時,左半邊+1=右半邊。若a<b,捨棄a的左半邊(包括中點)捨棄b的右半邊(保留中點)始終保持A B 等長。
在保留的兩個升序序列中,重複上述過程,直到兩個序列中均只含一個元素時為止,則較小者即為所求的中位數。
中位數演算法的程式如下:
#include <iostream> using namespace std; int al,ar,amid,bl,br,bmid; int a[100]={0}; int b[100]={0}; int FindMid(int al,int ar,int bl,int br) { while(1) { amid=(ar+al)/2; bmid=(br+al)/2; if(al==ar&&bl==br) { if(a[al]<b[bl]) return a[al]; else return b[bl]; } else { if((ar+al)%2==0) { if(a[amid]<b[bmid]) { al=amid; br=bmid; } else { bl=bmid; ar=amid; } else { if(a[amid]<b[bmid]) { al=amid+1; br=bmid; } else { bl=bmid+1; ar=amid; } } } } int main() { int num; int result; cin>>num; for(int i=0;i<num;i++) { cin>>a[i]; } for(int i=0;i<num;i++) { cin>>b[i]; } result=FindMid(0,num-1,0,num-1); cout<<result<<endl; }