每年奶牛们都要举办各种特殊版本的跳房子比赛,包括在河里从一块岩石跳到另一块岩石。这项激动人心的活动在一条长长的笔直河道中进行,在起点和距离起点 L 远的终点各有一块岩石 (1 ≤ L ≤ 10^9)。在起点和终点之间,有 N 块岩石 (0 ≤ N ≤ 50000),每块岩石与起点的距离分别为 Di (0 < Di < L)。
在比赛过程中,奶牛轮流从起点出发,尝试到达终点,每一步只能从一块岩石跳到另一块岩石。当然,实力不济的奶牛无法抵达终点,在河中间就退出比赛了。
农夫约翰为他的奶牛们感到自豪并且年年都观看了这项比赛。但随着时间的推移,看着其他农夫的胆小奶牛们在相距很近的岩石之间缓慢前行,他感到非常厌烦。他计划移走一些岩石,使得从起点到终点的过程中,最短的跳跃距离最长。他可以移走除起点和终点外的至多 M 块岩石 (0 ≤ M ≤ N)。
请帮助农夫约翰确定:移走这些岩石后,最短跳跃距离的最大值是多少?
输入
第 1 行包含以单个空格分隔的三个整数 L, N, M。
第 2 到 N + 1 行,每行一个整数,表示每个岩石与起点的距离。不会有两个岩石出现在同一个位置。
输出
输出一个整数,即最短跳跃距离的最大值。
示例输入
25 5 2
2
14
11
21
17
示例输出
4
提示
在移除位于 2 和 14 的两块岩石之后,最短跳跃距离达到了最大值 4 (从 17 到 21,或从 21 到 25)。
这个题目的要求是求出最短跳跃距离的最大值,这里就有点影响做题者的判断,什么叫做最短距离的最大值? 来,我给你举一个例子1,2,10 和另一个集合 3,5,15,两个集合中最短的分别是1 ,3 ,所以最大的值是3。就是这样的。
这个题目的意思就是牛可以跳无限远(河岸的宽度)和无限近0,题意是求出最短距离的最大值,就是保证所有牛都可以顺利过河的前提下,来使牛的跳跃距离最大。
但是怎么来实现呢,既然题目的要求是最小距离的最大值,肯定是从一个范围内逐渐得到的,这是我们就想到贪心,一个一个数据开始判断,但是一看数据量河的宽度是10的9次方,一个一个去遍历判断肯定会超时的。所以我们就会想到了二分查找并判断的思路来做这个题目。
下面是我的一点拙见,本身刚开始起步算法竞赛,对很多算法还不是很熟悉,请大家谅解。Orz Orz Orz ...
#include<iostream>
#include<cstdio>
#include<string.h>
#include<sstream>
#include<queue>
#include<algorithm>
#include<stack>
using namespace std;
const int maxn=50005;
typedef long long ll;
ll a[maxn];
ll l,n,m;
bool solve(ll mid)
{
int start=0;
int x=0;
for(int i=0;i<n;i++)
{
if(a[i]-start<mid)
{
x++;
}
else
start=a[i];
}
if(x>m)
return false;
return true;
}
int main()
{
while(scanf("%lld%lld%lld",&l,&n,&m)!=EOF)
{
for(int i=0;i<n;i++)
scanf("%lld",&a[i]);
sort(a,a+n);
ll left=0;
ll right=l;
ll ans;
while(left<=right)
{
int mid=(right+left)/2;
if(solve(mid))
{
ans=mid;
left=mid+1;
}
else
right=mid-1;
}
printf("%d\n",ans);
}
return 0;
}
我们在做一件事情时,如果说要求是使他最小并且在多种情况中,某一种情况的最小值是这几种情况中的最大值,我们人的意识应该是在一定的范围内不断寻找那个最适合的值,如果不合适偏小了,那就是他变大一点;如果太大了(假设这也是不满足条件),那我们就是他适当的减小次值。直到不能再去分的时候,这时应该就是这时的最优解了。对于这个题目,也是这样,要求找到最小值跳跃距离的最大值。在这里面,我们不禁想为什么还有最小跳跃距离的最大值,这时我们可以看看题设条件,就是这个主人公的牛有的懈怠偷懒,所以要移掉一些石头,石头的数量是固定的,不能随意的减少,所以就在这种情况下,就会有一些范围,又得将所有的牛能过河,又得调整牛跳跃的距离。这可能就会有范围之间不断的筛选出最优的答案。首先要确定牛可以跳跃的宽度范围,我们才可以进行二分搜索去确定最合适的答案,跳跃距离从 0到这个整个河宽 l 。然后再看一下这个判断函数里面是怎么写的?在这里我们判断是不是当前的跳跃距离可以移去多少石头?如果移去的石头有点多,我们就得将这个距离变得小一点,如果移去的石头比题目要求的还小,我们就可以将这个距离再二分的更大一点 ,直到最后不能再进行二分了,这时候就是最小值的最大值。(自己还是很菜)。