题目大意:
一个宽为L的河,有n块石头,至多能跳跃m次,给出n块石头距离跳远河岸的距离,问一次至少得跳跃多远的距离。
思路分析:
求出每一块石头距离前一块石头的距离(别忘了加到对面岸上也要一次跳跃,也当做一块石头处理就好),用二分查找,把这些距离分成m段,low也就为石头间距离最大的,high也就为河的宽度,找出这期间能把石头距离分成m段的最短长度(注意是最短,所以要以low为准)。
代码实现:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define Max(a,b) ((a)>(b)?(a):(b))
using namespace std;
const int maxn=500005;
int stone[maxn],l,n,m;
int main(){
while(~scanf("%d%d%d",&l,&n,&m)){
for(int i=0;i<n;++i) scanf("%d",&stone[i]);
sort(stone,stone+n);
int sum=stone[0],low=0,high=l,mid,cnt;
for(int i=1;i<n;++i){
stone[i]-=sum;
low=Max(low,stone[i]);
sum+=stone[i];
}
stone[n]=l-sum;
low=Max(low,stone[n]);
while(low<=high){
mid=(low+high)/2;
sum=0,cnt=1;
for(int i=0;i<=n;++i){
sum+=stone[i];
if(sum>mid){
sum=stone[i];
cnt++;
}
}
if(cnt>m) low=mid+1;
else high=mid-1;
}
printf("%d\n",low);
}
}