每年,奶牛都会举办一场特别版的跳房子活动,其中包括在河中小心翼翼地从岩石跳到岩石。兴奋发生在一条长而直的河流上,开始时有一块岩石,最后有另一块岩石,距离开始L单位(1≤L≤1,000,000,000)。沿着起始岩石和结束岩石之间的河流,出现N(0≤N≤50,000)更多的岩石,每个岩石从起点开始的整数距离Di(0 <Di <L)。
为了玩游戏,每头母牛依次从起始岩石开始,并尝试到达终点岩石的终点,只从岩石跳到岩石。当然,不那么灵活的奶牛永远不会进入最后的岩石,而是最终进入河中。
农民约翰为他的奶牛感到骄傲,每年都会观看这次活动。但随着时间的推移,他厌倦了看着其他农民的胆小的奶牛蜷缩在距离太近的岩石之间的短距离。他计划移除几块岩石,以增加牛必须跳到最后的最短距离。他知道他无法移除起始和结束的岩石,但他计算出他有足够的资源去除M岩石(0≤M≤N)。
FJ想知道在他开始移除岩石之前他能增加最短距离*的确切程度。帮助农夫约翰确定在移除最佳M岩石后,母牛必须跳跃的最大可能最短距离。
输入
第1行:三个以空格分隔的整数:L,N和M.
第2行...... N + 1:每一行包含一个整数,表示某些岩石远离起始岩石的距离。没有两个岩石共享相同的位置。
产量
第1行:一个整数,是除去M岩石后母牛必须跳跃的最短距离的最大值
题目大意:加上起点和中点两个点 ( N+2) 从中减去M个点使所有间隔中的最小值最大化;
用到二分法
二分模板:
while (r-l>1)
{
mid=(l+r)/2;
if(finds(mid)<=m) //(根据题意变换)
l=mid; //保存目前最合适的点
else
r=mid;
}
cout <<l<<endl; //输出那个最终最合适的点
AC 代码:
#include <iostream>
#include <algorithm>
using namespace std;
int L;
int n,m;
int arr[100000];
int finds(int mid) //find 函数是判断mid是否为合适的点
{ int next=1;
int k=0;
int nowpost=arr[0];
while (next<=n+1)
{
while (nowpost+mid>arr[next]&&next<=n+1) //mid既然是最小值,就不允许存在mid还小的arr[next]作为nowpost和nowpost+mid
{ //的中间值;
k++;
next++;
}
nowpost=arr[next];
next++;
}
return k;
}
int main()
{
cin >>L>>n>>m;
arr[0]=0;
arr[n+1]=L;
for(int i=1;i<=n;i++)
cin >>arr[i];
sort(arr,arr+n+2);
int l=0;
int r=2*L; //防止最小值是L的情况
int mid; //mid被认为是当前最小值去测试
while (r-l>1)
{
mid=(l+r)/2;
if(finds(mid)<=m) //(根据题意变换) 不断寻找最大化最小值的mid
l=mid; //找到一个满足条件继续找最大值
else
r=mid;
}
cout <<l<<endl;
return 0;
}