题目大概意思就是需要实现合并两个给出的递增序列为一个新递增序列,然后取中值。
解题思路
很清晰也很简明的题目,解决的方法也能很简单,归并排序里的合并步骤,或是暴力方法都很容易解决。
暴力方法
简单直观的方法
直接将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较小那个)就是输出的内容