最大什么的最小值,最小什么的最大值就是二分
10 3
5
2
10
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
using namespace std;
//最少花费时间,也就是让所有机器人花费时间中最大值的那一个花费时间最少
//最大什么的最小值,最小什么的最大值就是二分
//这道题的贪心策略是:优先扫左边的没扫的格子,然后扫右边的
int st[100005];
int n,k;
//判断当前的len(每个机器人扫的格子数量),能不能把所有方格都扫完
//优先扫左边的没扫过的格子,然后扫右边的
bool check(int len){
//前cur-1个格子扫完了,序号cur格子还没扫
int cur=0;
//遍历机器人
for(int i=0;i<k;i++){
//当前机器人全扫左侧格子,但是左侧格子还是有遗漏
if(st[i]-len>cur) return false;
//如果当前机器人的序号身处已经扫完的格子
//即当前机器人所在格子已经被扫过了
//那么当前机器人只需要往右扫就好了,不用往左扫
if(st[i]<=cur){
cur=st[i]+len-1;
}
//当前机器人左侧有格子没扫过
else{
cur+=len;
}
}
//判断全部格子都扫过了
return cur>=n;
}
void solve(){
cin>>n>>k;
for(int i=0;i<k;i++){
cin>>st[i];
}
sort(st,st+k);
//二分,找出符合条件的最短的机器人清扫的方格数量
//即对每个机器人的清扫方格数量进行二分(每个机器人扫的数量都是一样的)
//然后验证正确性即可,判断条件是清扫方格数量可以使得每个格子都能够扫到
int l=0,r=n,mid,ans;
while(l<=r){
mid=(l+r)>>1;
if(check(mid)){
r=mid-1;
ans=mid;
}
else{
l=mid+1;
}
}
//因为扫地要过去然后再回来,所以时间应该是(扫的格子数量-1)*2
cout<<(ans-1)*2;
// cout<<r*2;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
solve();
return 0;
}