组委会已经选择好了两块岩石作为比赛起点 0 和终点 L 。
在起点和终点之间,有 NN 块岩石(不含起点和终点的岩石)。
在比赛过程中,选手们将从起点出发,每一步跳向相邻的岩石,直至到达终点。
为了提高比赛难度,组委会计划移走一些岩石,使得选手们在比赛过程中的最短跳跃距离尽可能长。
由于预算限制,组委会至多从起点和终点之间移走 MM 块岩石(不能移走起点和终点的岩石)。
如果长度 Len 可以满足,那么当长度小于 Len 时也可以满足,所以我们可以二分出最大的 Len。
首先验证答案具有单调性:拿走的石头越多,最短跳跃距离越大,这就叫答案的单调性。
然后进行实现。我们假设最短跳跃距离为mid,接着我们写一个check函数,判断一下这个mid是否合法,如果合法,就尝试找一找有没有一个值比mid更大(l=mid),如果不合法,就把mid减小(r=mid-1)。
check函数:我们遍历一遍每一块石头,累计出有多少块石头之间的间隔<=mid,如果超过m个,就不合法,如果小于等于m,就合法。
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
int n, m, L;
vector<int> d;
bool check(int mx)
{
int cnt = 0, last = 0;
for (int i = 0; i <= n; i ++ ) {
if(d[i] - last < mx) cnt ++;
else last = d[i];
}
return cnt <= m;
}
int main(){
//std::ios::sync_with_stdio(false);
//std::cin.tie(nullptr);
cin >> L >> n >> m;
d.resize(n);
for (int i = 0; i < n; i ++ ) {
cin >> d[i];
}
d.push_back(L);
int l = 0, r = 1e9;
while(l < r) {
int mid = l + r + 1 >> 1;
if(check(mid)) l = mid;
else r = mid - 1;
}
cout << l << '\n';
return 0;
}