1029 Median (25 分)笔记
我颓了,一定要看清题目的限制范围。
题意
给出两个递增的数列,找出这个数列合并之后(并从小到大排好序)的中位数
解题过程
掉坑里了,最后没忍住看了题解。才发现忽略了long long。
开始就是普通合并然后快排找出中位数,没过之后我以为是超时的原因
为了避免排序超时,我的想法是尽量减少排序的数的个数。
可以发现中位数在一组数据的中间,中位数后面的数其实不会对中位数造成什么影响。把肯定比中位数大的数丢弃,排序的时间就缩短了。
显示比较两个数组的中位数,小的哪个设为xmin,大的设为xmax,xmin之前的数肯定在中位数之前,xmin数组中大于xmax的数肯定不在中位数之前
再加上xmax以及它之前的数,中位数一定在这些数中(这些数是所有数中最小的那些且数量超过两个数列数目之和的一半。)最后在排序找出中位数。
最后发现这两个点还是没过(原谅我忽视了系统提示的答案错误,还一直以为是超时导致的错误)忍不住看了题解,发现是数据类型出错了。改好数据类型之后就ac了,我最初提交的代码改了数据类型也过了(裂开)
解题思路
直接合并两个数组,再来个快排找中位数就🆗了
代码
#include<stdio.h>
#include<algorithm>
using namespace std;
long long int x[30000007],y[30000007],z[50000007],a;
int main()
{
int m,n,cnt=0,mid1,mid2;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%lld",&x[i]);
}
scanf("%d",&m);
for(int i=0;i<m;i++){
scanf("%lld",&y[i]);
}
mid1=(m-1)/2;
mid2=(n-1)/2;
if(x[mid2]<=y[mid1]){
for(int i=0;i<n&&(x[i]<=y[mid1]||i<=mid2);i++){
z[cnt++]=x[i];
}
for(int i=0;i<=mid1;i++){
z[cnt++]=y[i];
}
}else{
for(int i=0;i<=mid2;i++){
z[cnt++]=x[i];
}
for(int i=0;i<m&&(y[i]<=x[mid2]||i<=mid1);i++){
z[cnt++]=y[i];
}
}
sort(z,z+cnt);
// for(int i=0;i<cnt;i++){
// printf("%ld ",z[i]);
// }
printf("%lld\n",z[(m+n-1)/2]);
return 0;
}