- 把题目翻译成人话
- 在一条数轴上给定起点0和终点L
- 起点和终点之间有N个点,你可以删掉M个点
- 使得删除后,相邻点之间的距离d的最小值最大
- 看案例L=25 N=5 M=2
- N个点坐标 2 11 14 17 21
- 加上起点和终点0 2 11 14 17 21 25
- 相邻点之间的距离分别为 2 9 3 3 4 4 最小的d是2
- 删除2和14后 0 11 17 21 25
- 相邻点之间的距离分别为 11 6 4 4 最小的d是4
- 此时d最大,这就是题目的意思求最小的d的最大值
- 我们不难发现,最大的d一定满足d<=a[i]-a[i-1]
- 如果d>a[i]-a[i-1],就移除石头
- 统计移除的石头数量cnt,cnt<=M就是一个合法答案
- 利用check二分答案得到最大的d即可
- 代码11行是剪枝,cnt>M时直接返回false
- 别忘了终点也有一块石头,13行是判断终点的
#include<bits/stdc++.h>
using namespace std;
int a[50005];
int L,N,M;
bool check(int mid) {
int cnt = 0; // 移除的石头数
int last = 0; // 上一个石头的位置,初始是起点
for(int i=1; i<=N; i++) {
if(a[i] - last < mid) cnt++;
else last = a[i];//更新上一块石头的位置
if(cnt>M)return false;
}
if(L - last < mid) return false;
return cnt <= M;
}
int main(){
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin>>L>>N>>M;
for(int i=1;i<=N;i++)cin>>a[i];
int mn=1,mx=L;
int l=mn,r=mx,ans=0;
while(l<=r){
int mid = l + (r-l) / 2;
if(check(mid))ans=mid,l=mid+1;
else r=mid-1;
}
cout<<ans<<'\n';
return 0;
}