题意:
输入一个正整数
n
,1个正整数序列
思路:
计算可得中位数是
B
序列里的第
为了方便判断二分时每次的判断,要将A序列排成升序。
每次判断,可以用两个指针
i,j
记录头和尾的位置。因为A序列是单调递增的,所以说假如
i
元素与
现在可以统计差值小于现在二分的答案的数有几个了,用
cnt
记录,如果小于
cnt<k
,那么这个二分的答案一定是不正确的,如果说
cnt≥k
,那么满足这个条件最小的
cnt
一定就是答案,如果
cnt=k
,那
cnt
一定是答案;而且,就算没有
cnt=k
也没关系,因为这时一定有多个元素的差等于现在二分的答案,我们不妨看做去掉里面的几个,不影响答案。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
ll n, m, k, a1[100010];
bool check(ll x){
ll p = 1, cnt = 0;
for(int i = 1; i < n; i ++){
while(p+1 <= n && a1[p+1] - a1[i] <= x) p ++;
cnt += p-i;
}
return cnt < k;
}
int main(){
while(scanf("%lld", &n) != EOF){
m = n*(n-1)/2;
k = (m+1)/2;
for(int i = 1; i <= n; i ++) scanf("%lld", &a1[i]);
sort(a1+1, a1+1+n);
ll l = 0, r = a1[n], ans = 0;
while(l <= r){
int mid = (l+r)>>1;
if(check(mid)) l = mid + 1;
else ans = mid, r = mid - 1;
}
printf("%lld\n", ans);
}
return 0;
}