River Hopscotch POJ - 3258(二分答案)

每年奶牛们都要举办各种特殊版本的跳房子比赛,包括在河里从一块岩石跳到另一块岩石。这项激动人心的活动在一条长长的笔直河道中进行,在起点和距离起点 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 。然后再看一下这个判断函数里面是怎么写的?在这里我们判断是不是当前的跳跃距离可以移去多少石头?如果移去的石头有点多,我们就得将这个距离变得小一点,如果移去的石头比题目要求的还小,我们就可以将这个距离再二分的更大一点 ,直到最后不能再进行二分了,这时候就是最小值的最大值。(自己还是很菜)。    

发布了123 篇原创文章 · 获赞 83 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/tsam123/article/details/88259389