HDU 4004 The Frog's Games(二分+贪心)

The Frog’s Games
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 8574 Accepted Submission(s): 3992

Problem Description
The annual Games in frogs’ kingdom started again. The most famous game is the Ironfrog Triathlon. One test in the Ironfrog Triathlon is jumping. This project requires the frog athletes to jump over the river. The width of the river is L (1<= L <= 1000000000). There are n (0<= n <= 500000) stones lined up in a straight line from one side to the other side of the river. The frogs can only jump through the river, but they can land on the stones. If they fall into the river, they
are out. The frogs was asked to jump at most m (1<= m <= n+1) times. Now the frogs want to know if they want to jump across the river, at least what ability should they have. (That is the frog’s longest jump distance).

Input
The input contains several cases. The first line of each case contains three positive integer L, n, and m.
Then n lines follow. Each stands for the distance from the starting banks to the nth stone, two stone appear in one place is impossible.

Output
For each case, output a integer standing for the frog’s ability at least they should have.

Sample Input
6 1 2
2
25 3 3
11
2
18

Sample Output
4
11

题意

有一只青蛙要过河,河的宽度为L,河中有n个石子,石子直线排列,给你n个石子距离起跳位置的距离,青蛙过河一共只能跳跃m次,求问你青蛙最小跳跃能力(石子和石子或石子和岸之间的距离小于能力的都能跳过)

思路

二分青蛙的跳跃能力,二分用来找什么呢,二分来找的是青蛙的最大的能力使的跳跃次数大于m的能力,然后这个能力+1,就是我们我们要找的能力了,二分中的判断函数的时候首先我们要记录我们青蛙当前的位置d然后用upper_bound来找d+len(青蛙的步长)在哪个位置,因为用的是upper_bound返回的是第一个大于要找的数的数组指针当要找的数是最后一个数的时候又只返回最后一个数,所以我们的数组可以多加两项一个是L和L+9999999999来保证最后一项的下标可以到达对岸,然后每次跳跃的时候来记录步长,虽然有可能够不到下一块石头但是还是可以来继续加步数当大于m的时候就退出

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
using namespace std;
long long a[500005];
long long L,n,m;
int f(int len)
{
    int d=0;
    int step=0;
    while(d<L)
    {
        int num=upper_bound(a,a+n+2,d+len)-a;
        d=a[num-1];
        step++;
        if(step>m)
            break;
    }
    if(step>m)
        return 1;
    else
        return 0;
}
int main()
{
    while(scanf("%lld%lld%lld",&L,&n,&m)!=EOF)
    {
        a[0]=0;
        a[n+1]=L;
        a[n+2]=L+99999999;
        for(int i=1;i<=n;i++)
            scanf("%lld",&a[i]);
            if(m==1)
            {
                printf("%lld\n",L);
                continue;
            }
        sort(a,a+n+1);
        int l=a[1];
        int r=L;
        int mid;
        while(l<=r)
        {
            mid=(r+l)/2;
            int cas=f(mid);
            if(cas==1)
            {
                l=mid+1;
            }
            else
            {
                r=mid-1;
            }
        }
        printf("%d\n",r+1);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/ftx456789/article/details/79773121