题目链接:点我啊O(∩_∩)O~~
已知有两个等长的非降序序列
S
1
S1
S1、
S
2
S2
S2,求
S
1
S1
S1与
S
2
S2
S2并集的中位数
输入样例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
思想这里要求时间复杂度为
O
(
l
o
g
n
)
O(logn)
O(logn),那么就只能用二分来解决,如何二分呢?
假设
S
1
S1
S1、
S
2
S2
S2的中位数分别为
a
a
a、
b
b
b
①
①
①:若
a
=
b
a=b
a=b,则答案即为该值
②
②
②:若
a
<
b
a<b
a<b,则答案一定在
S
1
S1
S1的右半部分 +
S
1
S1
S1的左半部分(即把
S
1
S1
S1放到
S
2
S2
S2之前),即舍弃
S
1
S1
S1的
a
a
a 之前的部分,舍弃
S
2
S2
S2的
b
b
b 之后的部分
③
③
③:若
a
>
b
a>b
a>b,同
②
②
②,答案一定在
S
1
S1
S1的左半部分 +
S
2
S2
S2的右半部分(即把
S
2
S2
S2放到S1之前),即舍弃
S
1
S1
S1的
a
a
a 之后的部分,舍弃
S
2
S2
S2的
b
b
b 之前的部分
同时注意一下 l e f t > = r i g h t left>=right left>=right的时候直接返回就行了
#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);
}