1029 Median (25分)
题目链接:PAT A 1029
题目大意:给出两个升序的序列,要求输出将他们合并后序列的中位数。
思路分析:由于只需要输出合并序列的中位数,所以其实没必要将两个序列合并到一起。可以采用一种算法思想:two pointers。即定义两个变量i和j,分别从两个序列的开始扫描这两个序列,如果a[i]<b[j],就让i自增,否则让j自增,当到达中位数的下标时退出循环,再次比较a[i]和b[j],较小的那个就为中位数。
注意点1:中位数的下标应该是(n+m-1)/2,这是因为数组下标是从0开始,而且和为偶数的时候要输出左半边的那个数为中位数(题干里有说明)。
注意点2:两个数组的大小应该比n和m分别大1,最后一个元素用来存储int类型的最大值0x7fffffff(即2的31次方-1),这样即可以用来解决数组越界的问题。
注意点3:题目中数据量较大,输入输出时请使用scanf和printf,否则可能超时。
AC代码:
#include<iostream>
#include<vector>
using namespace std;
const int INF = 0x7fffffff; //int类型最大值
int main() {
int n, m;
scanf("%d", &n);
vector<int> a(n + 1);
for(int i = 0; i < n; i++)
scanf("%d", &a[i]);
a[n] = INF; //最后一个元素赋值为int类型最大值
scanf("%d", &m);
vector<int> b(m + 1);
for(int i = 0; i < m; i++)
scanf("%d", &b[i]);
b[m] = INF;
int median = (n + m - 1) / 2, i = 0, j = 0, cnt = 0; //cnt为计数器
while(cnt != median) {
if(a[i] < b[j]) //数组a中元素小,向右比较
i++;
else //数组b中元素小,向右比较
j++;
cnt++;
}
if(a[i] < b[j]) //输出较小的
printf("%d", a[i]);
else
printf("%d", b[j]);
return 0;
}