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×105) 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
题意:
给出两个已知递增的序列,长度分别为n 和 m, 将他们合并为一个新的递增序列后,求其中位数(个数为偶数时为左半部分的最后一个数)
思路:
本题很明显会采用序列合并的思路,依次比较两个数列的值,较小的值放在前面。但不用进行存储,用count 计数,到达中位数时,即为所求的数
注意:
- while 循环一开始没有想到,想要统计出到达中位数的那个数,只能采用 count 来计数
- 但是输出时,要输出a 与 b 数组中最小的那个,因为当 count = lenAns 时,还没有比较已经出了循环
- const int INF = 0x7fffffff; 定义int 型中最大值,将该值赋给 a b 数组的最后一个值,若不这样设置,可能存在一些答案错误的问题。原因:当一个序列扫描完毕,但 count 还没有到中位数的情况是,会发生访问越界问题。
- 依旧存在问题:内存超限
#include <cstdio>
const int maxn = 1000010;
const int INF = 0x7fffffff;
int a[maxn], b[maxn];
int main(){
int lenA, lenB;
scanf("%d", &lenA);
for(int i = 0; i < lenA; i++){
scanf("%d", &a[i]);
}
scanf("%d", &lenB);
for(int i = 0; i < lenB; i++){
scanf("%d", &b[i]);
}
a[lenA] = b[lenB] = INF;
int lenAns = (lenA + lenB - 1) / 2;
int i = 0, j = 0, count = 0;
while(count < lenAns){
if(a[i] < b[j])
i++;
else
j++;
count++;
}
if(a[i] < b[j])
printf("%d\n", a[i]);
else
printf("%d\n", b[j]);
return 0;
}
方法二:AC代码
只定义数组存储第一个序列,第二个序列不存储在数组中,依次读入temp中,然后记录count输出
#include <iostream>
using namespace std;
int k[200005];
int main(){
int n, m, temp, count = 0;
cin >> n;
for (int i = 1; i <= n; i++) //下标从1开始
scanf("%d", &k[i]);
k[n + 1] = 0x7fffffff;
cin >> m;
int midpos = (n + m + 1) / 2, i = 1; //i存储数组k的访问下标
for (int j = 1; j <= m; j++) {
scanf("%d", &temp);
while (k[i] < temp) {
count++;
if (count == midpos) cout << k[i];
i++;
}
count++;
if (count == midpos) cout << temp;
}
while (i <= n) { //如果第一个序列还没有比完
count++;
if (count == midpos) cout << k[i];
i++;
}
return 0;
}