7-1 两个有序序列的中位数 (25 分)
已知有两个等长的非降序序列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
思路:
这个题有点小问题,他中位数的定义就不是中位数,你就按他定义的来吧
一上来的思路就是先排序,就想到stl的vector,排好序按公式找出中位数的下标,然后对应下标直接输出就好
注意中位数的下标应该是
int m = (2*n + 1)/2 - 1;//因为题目说是从A1开始算所以之后还要减一
//int m = ((n + 1)/2 - 1)*2;我刚开始这么写的,测试样例有一个过不了,可能是怕m越界吧。。。我也不确定
还有你也可以不用stl,就写个找中位数的函数也成:
int FindMidNumber(int n)
{
int t1 = 0,t2 = 0;//为a,b两数组的下标
int m = (2*n + 1)/2 - 1;//m为中位数下标
//int m = ((n + 1)/2 - 1)*2;
while(t1 + t2 < m)//每次把小的那个书的下标++,相当于排序
{
if(a[t1] >= b[t2])
t2++;
else
t1++;
}
return a[t1] > b[t2] ? b[t2] : a[t1];
}
两种答案实现:
一:STL
#include <iostream>
#include <bits/stdc++.h>
#define maxn 100002
//int a[maxn],b[maxn];
using namespace std;
vector<int> ss;
int main()
{
int n,data1,data2;
cin>>n;
for(int i = 0;i < n;i++)
{
cin>>data1;
ss.push_back(data1);
}
for(int i = 0;i < n;i++)
{
cin>>data2;
ss.push_back(data2);
}
sort(ss.begin(),ss.end());
cout<<ss[n-1];//这里是关键
}
二.写函数
#include <iostream>
#include <bits/stdc++.h>
#define maxn 100002
int a[maxn],b[maxn];
using namespace std;
int FindMidNumber(int n)
{
int t1 = 0,t2 = 0;//为a,b两数组的下标
int m = (2*n + 1)/2 - 1;//m为中位数下标
//int m = ((n + 1)/2 - 1)*2;
while(t1 + t2 < m)//每次把小的那个书的下标++,相当于排序
{
if(a[t1] >= b[t2])
t2++;
else
t1++;
}
return a[t1] > b[t2] ? b[t2] : a[t1];
}
int main()
{
int n;
cin>>n;
for(int i = 0;i < n;i++)
{
cin>>a[i];
}
for(int i = 0;i < n;i++)
{
cin>>b[i];
}
cout<<FindMidNumber(n)<<endl;
return 0;
}