pat advanced level 1029

本文介绍了一种算法,该算法能在O(logn)的时间复杂度内找到两个已排序整数序列的中位数。通过逐个比较两个序列中的元素,文章详细解释了如何有效地确定中位数的位置。
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 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
/**********************
author: yomi
date: 18.6.15
ps:
long long int 都内存超限
改掉了之后 还剩最后一个样例内存超限。暂时弃疗。
还有一个问题: 为啥cnt < midPos?因为我们要找的是midPos啊 cnt == midPos跳出循环,此时比较a[i],b[j]即得结果。
我一直纠结 为什么下标为0还是下标为1, 都是cnt<midPos, 仔细想一想, 下标为0还是1只是决定了cnt的初值是0还是1,
最终退出条件都是cnt<midPos,因为我们要找的是midPos啊 cnt == midPos跳出循环,此时比较a[i],b[j]即得结果。
**********************/
#include <cstdio>

///--- O(logn) ---
const int maxn = 1000002;
const int inf = 0x7fffffff;
int a[maxn], b[maxn];

int main()
{
    int n, m, cnt = 1;
    scanf("%d", &n);
    for(int i=1; i<=n; i++){
        scanf("%d", &a[i]);
    }
    scanf("%d", &m);
    for(int i=1; i<=m; i++){
        scanf("%d", &b[i]);
    }
    a[n+1] = inf, b[m+1] = inf;///我以为这里只是防止一个数组扫描完,会造成数组越界的。然而这句做的可不止这些。
    int midPos = (m+n+1)/2; /// 12345         ///最后比较的时候,如果有一个数组扫描完了,那就是这个数组的最后一个元素的下一个元素
    int i=1, j=1;                              ///和另一个数组的当前元素比大小了,这就出现问题了,必须让最后一个元素的下一个为inf
    while(cnt < midPos /*&& i<=n && j<=m没必要*/){        ///最好直接memset为inf吧
        if(a[i] < b[j]){
            i++;
        }
        else{
            j++;
        }
        cnt++;
    }
//    while(cnt<midPos && i<=n){   ///加上了inf 这里就没必要写了
//        i++;
//        cnt++;
//    }
//    while(cnt<midPos && j<=m){
//        j++;
//        cnt++;
//    }
    //cout << i << ' ' << j <<endl;
    if(a[i] < b[j])
        printf("%d", a[i]);
    else
        printf("%d", b[j]);
    return 0;
}

/**
4 11 12 13 14
5 9 10 15 16 17
13
**/

/**    ---   O(nlogn)  ----
long long int a[2000010];

int Partition(int left, int right)
{
    int temp = a[left];
    while(left < right){
        while(left<right && a[right]>temp){
            right--;
        }
        a[left] = a[right];
        while(left<right && a[left]<=temp){
            left++;
        }
        a[right] = a[left];
    }
    a[left] = temp;
    return left;
}
void quicksort(int left, int right)
{
    if(left < right){
        int pos = Partition(left, right);
        quicksort(left, pos-1);
        quicksort(pos+1, right);

    }

}
int main()
{
    int n, m;
    scanf("%d", &n);
    for(int i=1; i<=n; i++){
        scanf("%lld", &a[i]);
    }
    scanf("%d", &m);
    for(int i=1; i<=m; i++){
        scanf("%lld", &a[i+n]);
    }
    //sort(a, a+m+n);
    quicksort(1, m+n);
//    for(int i=1; i<=m+n; i++){
//        cout << a[i] <<' ';
//    }
    printf("%lld", a[(m+n+1)/2]);

    return 0;
}
**/

 

转载于:https://www.cnblogs.com/AbsolutelyPerfect/p/9236351.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值