1. 程式人生 > >1029 Median (25 分)中位數

1029 Median (25 分)中位數

題目

Given an increasing sequence S of N integers, the median is the number at the middle position. For example, the median of S1 = { 11, 12, 13, 14 } is 12, and the median of S2 = { 9, 10, 15, 16, 17 } is 15. The median of two sequences is defined to be the median of the nondecreasing sequence which contains all the elements of both sequences. For example, the median of S1 and S2 is 13.

Given two increasing sequences of integers, you are asked to find their median.

Input Specification:
Each input file contains one test case. Each case occupies 2 lines, each gives the information of a sequence. For each sequence, the first positive integer N (

2 × 1 0 5 ≤2×10^​5 ​​ ) is the size of that sequence. Then N integers follow, separated by a space. It is guaranteed that all the integers are in the range of long int.

Output Specification:
For each test case you should output the median of the two given sequences in a line.

Sample Input:

4 11 12 13 14
5 9 10 15 16 17

Sample Output:

13

解題思路

  題目大意: 輸入兩個遞增序列,求合併之後的非遞減序列的中位數。
  解題思路1: 申請兩個陣列,合併資料,然後直接做排序,直接得到中位數,當然,這種方法肯定是要超記憶體的。但我還是用這種方式皮了一下,想看看哪幾個測試點資料量比較大……

/*
** @Brief:No.1029 of PAT advanced level.
** @Author:Jason.Lee
** @Date:2018-12-04 
** @status: wrong answer!
*/
#include<vector>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
vector<int> seq;
int main(){
	int N1,N2,temp;
	scanf("%d",&N1);
	for(int i=0;i<N1;i++){
		scanf("%d",&temp);
		seq.push_back(temp);
	}
	scanf("%d",&N2);
	for(int i=0;i<N2;i++){
		scanf("%d",&temp);
		seq.push_back(temp);
	}
	sort(seq.begin(),seq.end(),[](int x,int y){return x<y;});
	cout<<seq[ceil((N1+N2)/2.0)-1]<<endl;
	return 0;
} 

在這裡插入圖片描述

  解題思路2: 所以這道題需要用歸併的思想去做。先輸入一個數組,然後輸入第二個陣列的時候進行比較,每比較一次計算一次遍歷次數,先比較小的數,如果是第一個已經儲存在陣列中的數小,就往後遍歷該陣列,如果是輸入的數比較小,就繼續輸入,直到比較出符合資料的median個數即可。

/*
** @Brief:No.1029 of PAT advanced level.
** @Author:Jason.Lee
** @Date:2018-12-04 
** @status: Accepted!
*/

#include<vector>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;

int seq[200010];
int main(){
	int N1,N2,temp,median,index = 0;
	int res = -1;
	scanf("%d",&N1);
	for(int i=0;i<N1;i++){
		scanf("%d",&seq[i]);
	}
	scanf("%d",&N2);
	median = ceil((N1+N2)/2.0);// 或者用median = (N1+N2+1)/2
	for(int i=0;i<N2;i++){
		scanf("%d",&temp);
		while(temp>=seq[index]&&index<N1&&median){
			median--;// 此時開始數第一個序列
			index++;
		} 
		if(median==0){// median為0表示已經遍歷到中位數的位置了
			res = seq[--index];// 剛數完第一個序列,那麼結果肯定在第一個序列中
			break;
		}
		median--;// 如果上面那個break沒有中斷程式,說明還沒到中位數的位置,此處median減1,表示scanf的temp也算一個數
		if(median==0){
			res = temp;// 同理,如果median為0表示輸入的temp剛好是中位數
			break;
		}	
	}
	// 還有一種情況,中位數在第一序列中,第二序列輸入完了,但是還沒有遍歷到,那麼繼續遍歷第一序列
	if(median){
		while(median--){
		seq[index++];
		}
		res = seq[--index];
	}
	printf("%d\n",res);
	return 0;
} 

在這裡插入圖片描述

總結

  不參考任何資料,然後自己把題目快速做出來,並且最後發現自己的思路還和別人的不一樣,還是蠻開心的。