HDU4004The Frog's Games二分!二分!

题目在此

题目大意:一只青蛙被一条宽度为L的河挡住了去路,垂直河岸有一些石头露出水面,这些石头在一条直线上。现在青蛙想要借助这些石头过河,但是最多跳m次,问青蛙最小弹跳多远。

题目分析:要求青蛙的最小弹跳距离,因为青蛙不能落水,所以他至少要跳相邻2块石头以及靠岸的石头与岸边的距离的最小值,青蛙最大弹跳为L。青蛙的弹跳范围有了,于是我们可以选择二分答案。每次估算一个距离,再检查一下,这个距离是否满足青蛙能在m次以内过河。检查的时候为了提高效率,我们可以用二分查找迅速定位青蛙的下一个落脚点是哪块石头。详情请见代码:

#include <iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

#define N 500005

int stone[N];
int l,n,m;

int find(int dis)
{
    int l,r,mid;
    l = 0;r = n;
    while(l <= r)
    {
        mid = (l + r)>>1;
        if(dis >= stone[mid])
            l = mid + 1;
        else
            r = mid - 1;
    }
    return l - 1;
}

int main()
{
    int i;
    while(scanf("%d%d%d",&l,&n,&m) != EOF)
    {
        int top = l;
        int bottom = 1;
        int mid;
        for(i = 0;i < n;i ++)
        {
            scanf("%d",&stone[i]);
        }
        sort(stone,stone + n);
        stone[n] = l;//把对岸当成最后一块石头

        while(top >= bottom)
        {
            mid = (top + bottom)>>1;
            int cnt = 0;
            int j;
            i = find(mid);
            if(i == -1)
            {
                bottom = mid + 1;
                continue;
            }
            cnt ++;
            int flag = 0;
            while(stone[i] < l)
            {
                j = i;
                i = find(mid + stone[i]);
                if(j == i)//说明在当前的弹跳距离mid,青蛙跳不到下一块石头
                {
                    flag = 1;
                    break;
                }
                cnt ++;
            }
            if(flag)
            {
                bottom = mid + 1;
                continue;
            }
            if(cnt > m)
                bottom = mid + 1;
            else
                top = mid - 1;
        }
        printf("%d\n",bottom);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值