7-4 两个有序序列的中位数
已知有两个等长的非降序序列S1, S2, 设计函数求S1与S2并集的中位数。有序序列A0,A1,⋯,AN−1的中位数指A(N−1)/2值,即第⌊(N+1)/2⌋个数(A0为第1个数)。
输入格式:
输入分三行。第一行给出序列的公共长度N(0<N≤100000),随后每行输入一个序列的信息,即N个非降序排列的整数。数字用空格间隔。
输出格式:
在一行中输出两个输入序列的并集序列的中位数。
输入样例1:
5
1 3 5 7 9
2 3 4 5 6
输出样例1:
4
输入样例2:
6
-100 -10 1 1 1 1
-50 0 2 3 4 5
输出样例2:
1
程序设计思路:
先建立三个数组,数组一和数组二分别存储S1和S2,数组三为他们俩的并集,然后求数组三的中位数即可。
程序代码如下:
//代码可能存在些问题,可能有某些测试点过不去
#include <stdio.h>
#include <stdlib.h>
#define N 10^5+5
void sort(int *a,int len) //冒泡法排序
{
int i=0;
int j;
int t;
for(i=0;i<len;i++)
{
for(j=0;j<len-i-1;j++)
{
if(a[j]>a[j+1])
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
}
}
int main()
{
int n;
int i=0,j=0,k=0;
int *sz1;
sz1 = (int*)malloc(N*sizeof(int));
int *sz2;
int *sz3;
int mid;
int flag=0;
sz2 = (int*)malloc(N*sizeof(int));
sz3 = (int*)malloc(N*2*sizeof(int));
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&sz1[i]);
sz3[i]=sz1[i];
}
for(i=0;i<n;i++){
scanf("%d",&sz2[i]);
}
k=n;
for(i=0;i<n;i++){
for(j=0;j<n;j++){
if(sz2[i]==sz3[j]){
flag=1; //如果数组2的i项有和数组3中的某项相同的话,flag置为1
}
}//for j
if(flag==0){ //flag为0说明数组2的第i项和数组3中的每一项都不同,说明数组2是新的一项
sz3[k]=sz2[i]; //将新的这项加入到数组三的末尾
k++;
}
flag=0;
}//for i
sort(sz3,k); //对数组三的前k项进行冒泡法排序
if(k%2==0){ //计算中位数
mid=(sz3[k/2]+sz3[k/2-1])/2;
printf("%d",mid);
}
else {
mid=sz3[k/2+1];
printf("%d",mid);
}
return 0;
}//main
我求S1和S2的并集的方法较为麻烦,但便于理解。就是相同的元素不插到S3后面,最后再同一排序。
懒得改进了,就这样吧。