第一题:T1保持距离
标签:二分答案
题意:给定
n
n
n个坐标
x
1
,
x
2
,
…
,
x
n
x_1,x_2,…,x_n
x1,x2,…,xn 请从中挑出
k
k
k个坐标(
k
k
k为给定值),使得选出的坐标两两之间的最短距离最大。
题解:非常经典的二分答案最大化最小值的题型,先对坐标从小到大排序,然后二分枚举最短距离
m
i
d
mid
mid,求当前情况下能够满足相邻坐标大于等于
m
i
d
mid
mid的有多少个,如果不够
k
k
k个,那么我们需要把这个距离变小一点(即把搜寻区间调整到
[
l
,
m
i
d
−
1
]
[l,mid-1]
[l,mid−1]);反之,够的话把距离变大(搜寻区间调整到
[
m
i
d
+
1
,
r
]
[mid+1,r]
[mid+1,r]),同时把
a
n
s
ans
ans更新一下。
tips:二分搜索的前提是序列是有序的,二分答案的前提是 满足条件的答案是单调有序的(具有单调性)
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n, k, x[300005];
int main() {
cin >> n >> k;
for (int i = 1; i <= n; i++) cin >> x[i];
sort(x + 1, x + 1 + n);
ll l = 0, r = 1e10, ans = 1e10;
while (l <= r) {
ll mid = (l + r) >> 1;
// cnt: 选出的坐标个数 pre: 上一个的坐标
ll cnt = 1, pre = 1;
for (int i = 2; i <= n; i++) {
if (x[i] - x[pre] >= mid) {
cnt++;
pre = i;
}
}
if (cnt >= k) {
ans = mid;
l = mid + 1;
} else {
r = mid - 1;
}
}
cout << ans << endl;
return 0;
}