PAT A1029 Median

在这里插入图片描述
题目大概意思就是需要实现合并两个给出的递增序列为一个新递增序列,然后取中值。

解题思路

很清晰也很简明的题目,解决的方法也能很简单,归并排序里的合并步骤,或是暴力方法都很容易解决。

暴力方法

简单直观的方法
直接将S1和S2放入S3中,然后使用强大的algorithm库的sort排序之后直接可以得到结果。
这个方法不需要S1,S2是否有序,反正也要再次排序,复杂度不变

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long LL;
LL seq1[1000010]={0},seq2[1000010]={0};
LL seq[10000100]={0};
int main(){
    int N1,N2;
    scanf("%d",&N1);
    for(int i=0;i<N1;i++){
        scanf("%lld",&seq1[i]);
        seq[i]=seq1[i];
    }
    scanf("%d",&N2);
    for(int i=0;i<N2;i++){
        scanf("%lld",&seq2[i]);
        seq[i+N1]=seq2[i];
    }
    int N3=N1+N2;
    sort(seq,seq+N3);
    int median=(N3-1)/2;
    printf("%lld\n",seq[median]);
}

sort好牛,根本不需要你去实现排序的内部结构

使用归并

只要你会归并排序,就可以按照两个有序数组排序进去然后直接得到S3

//大致代码和上面差不多,只需要重新定义一下归并函数
void merge(LL A[],LL B[],LL C[],int n,int m){
    int i=0,j=0,index=0;
    while(i<n&&j<m){
        if(A[i]<=B[j]){
            C[index++]=A[i++];
        }
        else{
            C[index++]=B[j++];
        }
    }
    while(i<n){C[index++]=A[i++];}
    while(j<m){C[index++]=B[j++];}
}

这个方法也很容易想到,由归并马上可以得到结果

进阶一点

我能想到的第三个方法。
因为题目只需要输出S1和S2的合并之后的中间值,并不需要S3的出现,所以甚至可以不需要先合并成S3,直接就在边合并S1,S2的过程中得到median值,输出就好。

//可以用以个median_count值来记录当前合并序列的下标
//到(N1+N2-1)/2就输出即可
void median(LL A[],LL B[],int n,int m){
	int median_pos=(m+n-1)/2;
	int i=0,j=0,median_count=0;
	while(median_count<median_pos)
	{	if(seq1[i]<seq2[i])i++;
		else j++;
		median_count++;
	}
	if(seq1[i]<seq2[j])
	{printf("%lld\n",seq1[i]);}
	else{
	printf("%lld\n",seq2[j]);
	}
}

在遍历S1和S2的时候,每次都让两个序列里较小的那个放入S3中(实际上这个S3是不存在的)只需要将下标相应增加就好,加入了一个记录位置的median_count,当这个值到达median_pos时候,此时对应的下一个元素(S1和S2较小那个)就是输出的内容

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值