POJ-3258___River Hopscotch——解题报告 二分法

原题链接:http://poj.org/problem?id=3258

River Hopscotch
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 17439   Accepted: 7295

Description

Every year the cows hold an event featuring a peculiar version of hopscotch that involves carefully jumping from rock to rock in a river. The excitement takes place on a long, straight river with a rock at the start and another rock at the end, L units away from the start (1 ≤ L ≤ 1,000,000,000). Along the river between the starting and ending rocks, N (0 ≤ N ≤ 50,000) more rocks appear, each at an integral distance Di from the start (0 < Di < L).

To play the game, each cow in turn starts at the starting rock and tries to reach the finish at the ending rock, jumping only from rock to rock. Of course, less agile cows never make it to the final rock, ending up instead in the river.

Farmer John is proud of his cows and watches this event each year. But as time goes by, he tires of watching the timid cows of the other farmers limp across the short distances between rocks placed too closely together. He plans to remove several rocks in order to increase the shortest distance a cow will have to jump to reach the end. He knows he cannot remove the starting and ending rocks, but he calculates that he has enough resources to remove up to rocks (0 ≤ M ≤ N).

FJ wants to know exactly how much he can increase the shortest distance *before* he starts removing the rocks. Help Farmer John determine the greatest possible shortest distance a cow has to jump after removing the optimal set of Mrocks.

Input

Line 1: Three space-separated integers:  LN, and  M 
Lines 2.. N+1: Each line contains a single integer indicating how far some rock is away from the starting rock. No two rocks share the same position.

Output

Line 1: A single integer that is the maximum of the shortest distance a cow has to jump after removing  M rocks

Sample Input

25 5 2
2
14
11
21
17

Sample Output

4

Hint

Before removing any rocks, the shortest jump was a jump of 2 from 0 (the start) to 2. After removing the rocks at 2 and 14, the shortest required jump is a jump of 4 (from 17 to 21 or from 21 to 25).


题目大意:

给出一条长L的河流,中间有N块石头、最多能取走其中的M块。

问取走后任意两个石头间的最小距离的最大值是多少?


解题思路:

石头间距不定,则可以用二分从大到小筛选出较小距离的间距,从中剔除。

如果二分的中间值较大,则会出现剔除的石头数大于M,则继续二分;反之亦然,知道max==min


代码思路:

1、用数组存储石头地点并排序

2、二分的中间值作为参数对间距进行判断

3、若间距过大导致剔除的石头数大于M则max=mid-1

4、若间距过小且max!=min,则min=mid+1

5、最后返回相同的mid则为ans


核心:本题的关键在于用二分法判断河流的间距,从而依次排除较大或较小的答案;另一个关键点在于最后的ans从哪里取,二分的结果刚好是大于最后一次剔除的最小值并小于能继续剔除的值,即max==min==mid!


代码:

#include<iostream>
#include<algorithm>
using namespace std;
int l,m,n,num[50005],ans;
bool solve(int a)
{
	int sum=0,temp=0;
	for(int i=1;i<=n+1;i++)
	{
		if(num[i]-num[temp]<a)
		{
			sum++;    //两点间距离大于a,去掉一个点
			if(sum>m) 
				return false;    //去掉的点大于m,返回
		}
		else temp=i;    越过剔除的点
	}
	return true;
}




int main()
{
	std::ios::sync_with_stdio(false);
	int max,min,mid;
	cin>>l>>n>>m;
	for(int i=1;i<=n;i++) cin>>num[i];
	num[0]=0;
	num[n+1]=l;
	sort(num,num+n+1);
	max=l;
	min=0;
	while(max-min>=0)
	{
		mid=(max+min)/2;
		if(solve(mid))
		{
			ans=mid;    //在此记录答案!!!
			min=mid+1;    //返回为真,即剔除的石头数偏少,可以增大 
		}
		else max=mid-1;
	}
	cout<<ans;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/scar_halo/article/details/79415168
今日推荐