51nod 1243 排船的问题
求最长绳子最短,考虑二分答案,判断时我们优先向左放,看是否能全放下。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int n,x,m;
int pos[50005];
int check(int mid){
int p=x;//偏差地图
int x2=x*2;
int mx=m+x;//偏差地图
for(int i=1;i<=n;i++){
p=max(pos[i]-mid,p);//找最左边的点
if(p>pos[i]+mid){//超过限制
return 0;
}
p+=x2;//移动左端点
if(p>mx){//超过移动后的地图边界
return 0;
}
}
return 1;
}
int main(){
ios::sync_with_stdio(false);
cin>>n>>x>>m;
for(int i=1;i<=n;i++){
cin>>pos[i];
}
if(2*n>m/x){//全部船的长度之和超过m
cout<<-1;
return 0;
}
int ans=0;
int l=0,r=m,mid;
while(l<=r){//二分
mid=(l+r)>>1;
if(check(mid)){//可以用这个长度
r=mid-1;
}
else{
l=mid+1;
}
ans=r+1;//最后合理的答案
}
cout<<ans;
return 0;
}