Cpp环境【POJ3258】【Usaco2006】【Vijos1329】River Hopscotch跳石游戏

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 M 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 M rocks.


  每年奶牛们举行一场奇特的活动。他们从左岸出发,一个个小心地跳过河上的石头,最后跳到右岸。左右岸上各有一块石头,分别是起点和终点,而它们之间有N块石头在河上,它们与两岸的两块石头处在同一条直线上。左右岸相距L个单位长度,而每块石头到左岸都有一个距离Di(0 < Di < L)。
  Farmer John很自豪地看着他的奶牛们一个个跳过河,但是渐渐地他厌倦了。他希望移走河上的一些石头,使得剩下的石头(包括岸上的)中,最近的两个石头间的距离增加。然而因为精力有限,他不能移走太多石头,最多移走M(0 <= M <= N )块。他想知道石头间的距离最长是多少。

Input  【输入格式】

Line 1: Three space-separated integers: L, N, 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.


  第1行:三个整数L,N和M。
  第2..N+1行:每行一个整数,表示石头到左岸的距离。输入保证没有两块石头会在同一处。

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

【数据范围】  

  1<=N<=50000
  1<=L<=1000000000

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).


  移走距离左岸2和14的石头,还剩下0,11,17,21,25,他们之间的最小距离为4.

Source  

原题传送门

【思路梳理】

  仔细思考还是会发现是不难的一道题,虽然说有点绕、感觉不好处理,但是考虑到“瓶颈(最小值最大)”的问题不难想到使用二分猜答案的思想,猜测能达到的瓶颈的最大值是多少,在判断时采用一点贪心思想就可以。
  贪心策略:以第一个石头(手动加入一个左岸的起点)为起点,移走与它的距离小于x的石头并统计移走的石头个数removal_num,直到下一块石头j与它的距离大于等于x或者移走的石头数大于等于m,再以第j块石头为起点搜索后面需要移走的石头即可。

【Cpp代码】
#include
#include
#include
#define maxn 50005
using namespace std;
int l,n,m,dist[maxn];

bool Judge(int x)//判断猜测值是否成立
{
    int removal=0,i=0;//i从0(手动加入的左岸起点)开始,防止漏掉第一块石头
    while(i<=n)
    {
        int j=i+1;//移走所有与i距离小于x的石头
        while(j<=n && dist[j]-dist[i]if(removal>m)   return false;//移走的个数大于了m说明已经不成立
            j++;
        }
        i=j;    
    }
    return true;
}


void solve()//二分猜答案
{
    int s=0,d=l,ans=0;
    while(s<=d)
    {
        int mid=s+d>>1;
        if(Judge(mid))
            ans=mid,s=mid+1;
        else d=mid-1;
    }

    printf("%d",ans);
}

int main()
{
//  freopen("in.txt","r",stdin);
    scanf("%d%d%d",&l,&n,&m);

    for(int i=1;i<=n;i++)
        scanf("%d",&dist[i]);

    dist[0]=0;//左岸,起点 
    sort(dist,dist+1+n);

    solve();
    return 0;
}

你可能感兴趣的:(基础算法之五,贪婪的心,基础算法之一,查找搜索&排序,分治算法之二分猜答案,难度评级,Lower,than,Average)