题目思路:我们可以想到用二分法来解答这个题,将最短跳跃距离的最大值当作已知量,然后用二分法来试这个答案,直到最后去掉石头的数量与题目已知的数量匹配时,最短跳跃距离取可以满足题意的最大值即可。
具体代码:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
int L, N, M;
int n[50010] = { 0 };
int out(int x) { //判断函数
int i = 0;
int now = 0;
int cnt = 0;
while (i < N + 1) { //注意N块石头不包含首尾两块
i++;
if (n[i] - n[now] < x) { //计算两块石头间的距离,与mid即x比较
cnt++; //如果小于x(mid)就移除
}
else {
now = i; //否则,更新前一块石头为当前块
}
}
if (cnt > M) { //移出的石头过多,mid过大
return false;
}
else { //移出的石头少,mid过小,再看mid如果再大的话是否也能满足条件
return true;
}
}
int main()
{
cin >> L >> N >> M;
for (int i = 1; i <= N; i++) {
cin >> n[i];
}
n[N + 1] = L;
int left = 1;
int right = L;
int ans = 0;
while (left <= right) {
int mid = left + (right - left) / 2; //二分求中间值
if (out(mid)) {
ans = mid;
left = mid + 1; //函数为真,说明mid过小
}
else {
right = mid - 1; //否则mid过大,缩小范围
}
}
cout << ans << endl;
return 0;
}