A1029 Median (25 分)(求两个递增序列的中位数)(two pointer)

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×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

题意:

给出两个已知递增的序列,长度分别为n 和 m, 将他们合并为一个新的递增序列后,求其中位数(个数为偶数时为左半部分的最后一个数) 

思路:

本题很明显会采用序列合并的思路,依次比较两个数列的值,较小的值放在前面。但不用进行存储,用count 计数,到达中位数时,即为所求的数

注意:

  1. while 循环一开始没有想到,想要统计出到达中位数的那个数,只能采用 count 来计数
  2. 但是输出时,要输出a 与 b 数组中最小的那个,因为当 count = lenAns 时,还没有比较已经出了循环
  3. const int INF = 0x7fffffff; 定义int 型中最大值,将该值赋给 a b 数组的最后一个值,若不这样设置,可能存在一些答案错误的问题。原因:当一个序列扫描完毕,但 count 还没有到中位数的情况是,会发生访问越界问题。
  4. 依旧存在问题:内存超限
#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;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值