HDU4004The Frog's Games 二分

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

Hint

题意

小青蛙过河 河宽l 有n块石头 问小青蛙过河m次蹦过去 需要的最小最大跳跃距离

题解:

AC代码

#include <cstdio>
#include <iostream>
#include <queue>
#include <map>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
const int N = 5e5+5;
int a[N];
int l,n,m;
bool check(int k){
/*啊啊啊啊啊啊啊啊啊啊啊 这里真的考验代码能力啊啊啊*/
/*在尽量使用最大跳跃距离的条件下计算最少跳过去的次数*/
    int t = 0;
    int ans = 1;
    /*开区间*/
    for (int i = 1; i <= n; ++i){
        if (a[i]-a[t]<=k&&a[i+1]-a[t]>k){
            ans++;
            t = i;
        }
    }
    if (ans<=m) return true;
    return false;
}
int main(){
    while (scanf("%d%d%d",&l,&n,&m)!=EOF){
        for (int i = 1;i <= n; ++i){
            scanf("%d",&a[i]);
        }
        if (m==1) printf("%d\n",l);
        else {
            a[n+1] = l;
            sort(a+1,a+n+1);
            int d=0;
            /*这样就保证青蛙跳跃的距离至少能挨着石头一个一个蹦过去 即满足能过去的距离*/
            for (int i = 1; i <= n+1; ++i){
                d = max(a[i]-a[i-1],d);
            }
            /*在使用二分查找 在满足能过去的距离和最大距离l之间找到满足m次的一次最大能蹦的距离*/
            int lt = d,rt = l;
            while (lt<=rt){
                int mid = (lt+rt)>>1;
                if (!check(mid)) lt = mid+1;
                else {
                    rt = mid-1;
                }
            }
            printf("%d\n",rt+1);
        }

    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值