这个有特殊处理,自己的逻辑太不严谨,老想不全面。详细见代码注释
code:
#include <bits/stdc++.h>
#define int long long
using namespace std;
int a[100005] ;
int L , n , M ;
bool check(int x){
int nowat = 0 ;
int remov = 0 ;
for(int i = 1 ; i <= n ; i++) {
if(a[i]-a[nowat]<x){//这块石头不能被跳,忽略它。(可以想想如果不移走这块石头会怎么样)
remov++;//移除一块石头花费1
}else{
nowat = i ;//找到了nowat点之后第一个距离nowat不小于x的石头,跳到这块石头上
}
}
/**这个地方可以着重考虑一下,大概就是两种情况。
* 第一种情况,只剩下起点和终点,看看是否要执行remov++(自增之后一定是n+1了);
* 第二种情况,起点和终点之间的点至少一个剩下一个,这时候要讨论此时踩着的点距离终点的距离,看要不要把脚下踩着的石头移走。
* **/
if(L - a[nowat] < x && remov < n) remov++;
return remov <= M;
}
signed main()
{
//freopen("in","r",stdin);
cin >> L >> n >> M ;
for(int i = 1 ; i <= n ; i++) {
scanf("%lld",&a[i]);
}
int l = 0 , r = 1000000001;
while(l+1<r){
int mid = (l + r)/2;
if(check(mid))l = mid ;
else r = mid ;//长度为mid不满足,mid+1指定也不满足。解一定不位于[mid+1,r]
}
//最终获得答案所在区间[l,r],其中 r = l + 1
if(check(r))cout << r << endl;
else cout << l << endl ;
return 0 ;
}