题目
Given an increasing sequence S of N integers, the median is the number at the middle position. For example, the median of S 1 = { 11 , 12 , 13 , 14 } S_1 = \{ 11, 12, 13, 14 \} S1={11,12,13,14} is 12 12 12, and the median of S 2 = { 9 , 10 , 15 , 16 , 17 } S_2 = \{ 9, 10, 15, 16, 17 \} S2={9,10,15,16,17} is 15 15 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 S 1 S_1 S1 and S 2 S_2 S2 is 13 13 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 ) N(\le2\times10^5) N(≤2×105) is the size of that sequence. Then N N 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
题目大意
给出两个递增的有序序列,要求求出两个序列合并后(后并后的序列还是递增)的中位数。
解题思路
题目给的数据范围比较大,显然不可能直接合并两个数组,这里采用双指针的思想,我们这样想,两个数组合并后的中位数一定是mid = (len1 + len2 - 1)
,那么我们可以模拟排序过程,指针i
指向
S
1
S_1
S1,指针j
指向
S
2
S_2
S2,再定义一个计数器,然后逐一比较s1[i]
和s2[j]
,若s1[i]<s2[j]
,则说明s[i]
排在s2[j]
的前面,此时i++
,否则j++
,
与此同时count++
,当count == mid
时,就已经找到中位数了。
题目有一个需要注意的地方
S
1
S_1
S1和
S
2
S_2
S2的长度不一致,所以i
和j
在加一的过程中可能会越界,这里采用一个巧妙的方法可以避免这种情况,具体见代码。
代码
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int MAX = 200001;
const int INF = 0x7fffffff;
int s1[MAX];
int s2[MAX];
int main(){
int len1, len2;
scanf("%d", &len1);
for(int i=0; i<len1; i++)
scanf("%d", &s1[i]);
scanf("%d", &len2);
for(int i=0; i<len2; i++)
scanf("%d", &s2[i]);
//避免长度不一致而产生越界的为问题,是一个很巧妙的方法
s1[len1] = s2[len2] = INF;
int count = 0, mid = (len1 + len2 - 1)/2;
int i = 0, j = 0;
while(count < mid){
if(s1[i] < s2[j]){
i++;
}
else{
j++;
}
count++;
}
if(s1[i] < s2[j])
printf("%d\n", s1[i]);
else
printf("%d\n", s2[j]);
return 0;
}