题意:青蛙通过河中央的n块石头过河, 所有石头均在与河岸垂直的一条线上,给定每块石头到河岸的距离,给出河的宽L,给定青蛙跳的次数上限m(即青蛙必须经过m或小于m次跳动,过到河对岸),求出青蛙能够过河的最小步长。
当步长为河宽时,青蛙必能跳过,二分步长,求最小步长。
#include<iostream>
#include<cstring>
#include<algorithm>
#define maxn 500010
using namespace std;
int l,n,m; //河的宽度,n块石头,最多跳n步
int stone[maxn];
int pd(int jump){
int cnt=0,i=0;
if(m*jump<l) return false;
for(int j=1;j<=n+1;j++)
if(stone[j]-stone[i]>jump)
if(j==i+1) return false; //出现相邻的石子距离大于步长
else {
i=(--j); //下次操作j++,此时的i记录需要跳的位置
cnt++;
}
if((++cnt)>m) return false; //跳过河的最后一步没有记录,所以cnt++;
return true;
}
int main(){
while(cin>>l>>n>>m){
memset(stone,0,sizeof(stone));
for(int i=1;i<=n;i++)
scanf("%d",&stone[i]);
stone[n+1]=l; //最后还得跳上岸
sort(stone+1,stone+n+1);
//二分步长
int low=0,high=l;
int mid;
while(low<=high){
mid=(high+low)/2;
if(pd(mid)) high=mid-1;
else low=mid+1;
}
cout<<low<<endl;
// cout<<mid<<endl;
}
return 0;
}