算法训练营 训练 差的中位数(二分法)

题目描述

给定 N N N个数 X 1 , X 2 , . . . , X N X_1,X_2,...,X_N X1,X2,...,XN,计算每一对数字的差: ∣ X i − X j ∣ |X_{i} - X_{j}| XiXj 1 ≤ i < j ≤ N 1 \leq i < j \leq N 1i<jN。请尽快找到差的中位数!
注意,在这个问题中,中位数被定义为第 m / 2 m/2 m/2个数, m m m为差的数量。

输入:输入由几个测试用例组成。每个测试用例的第1行都为N。然后给出N个数字,表示 X 1 , X 2 , . . . , X N X_1,X_2,...,X_N X1,X2,...,XN X i ≤ 1 0 9 , 3 ≤ N ≤ 1 0 5 X_{i} \leq 10^{9},3 \leq N \leq 10^{5} Xi1093N105)。

输出:对于每个测试,都单行输出差的中位数。

#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
int find(int t);
bool check(int val);
int a[100000];
int m, n;
int ans = -1;

int main() {
    while (cin >> n) {
        cin.get();
        for (int i = 0; i < n; i++) {
            cin >> a[i];
        }
        cin.get();
        sort(a, a + n);
        m = n * (n - 1) / 4;
        int l = 0, r = a[n - 1] - a[0];
        while (l <= r) {
            int min = (l + r) / 2;
            if (check(min)) {
                l = min+1;
                ans = min;
            }
            else {
                r = min - 1;
            }
        }
        cout << ans << endl;
    }
}
int find(int t) {//找到数组a中第一个大于等于t的元素的位置
    int l = 0, r = n - 1, ans = -1;
    while (l <= r) {
        int min = (l + r) / 2;
        if (a[min] >= t) {
            ans = min;
            r = min - 1;
        }
        else {
            l = min + 1;
        }
    }
    return ans;
}
bool check(int val) {//返回true:中位数比val大		返回false:中位数比val小
    int count = 0;
    for (int i = 0; i < n; i++) {
        count+=n-(lower_bound(a,a+n,a[i]+val)-a);
    }
    return count > m;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

羽星_s

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值