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 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的长度不一致,所以ij在加一的过程中可能会越界,这里采用一个巧妙的方法可以避免这种情况,具体见代码。

代码

#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;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值