已知有两个等长的非降序序列 、 ,求 与 并集的中位数
输入样例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之前),即舍弃
的
之后的部分,舍弃
的
之前的部分
同时注意一下 的时候直接返回就行了
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
void f(int a[], int b[], int l1, int r1, int l2, int r2){
if(l1>=r1 || l2>=r2) {
printf("%d\n", a[l1]>b[l2]?b[l2]:a[l1]);
return;
}
int mid1 = (l1 + r1)/2;
int mid2 = (l2 + r2)/2;
printf("%d %d\n", mid1, mid2);
if(a[mid1] == b[mid2]){
printf("%d\n", a[mid1]);
return;
}
else if(a[mid1] < b[mid2]){
if((l1+r1)&1) f(a, b, mid1+1, r1, l2, mid2); //偶数个元素
else f(a, b, mid1, r1, l2, mid2);
}
else {
if((l2+r2)&1) f(a, b, l1, mid1, mid2+1, r2);
else f(a, b, l1, mid1, mid2, r2);
}
}
int main(){
int n, a[100010], b[100010];
scanf("%d", &n);
for(int i=1; i<=n; i++) scanf("%d", a+i);
for(int i=1; i<=n; i++) scanf("%d", b+i);
f(a, b, 1, n, 1, n);
}