您的位置:首页 > 其它

hdu 4004(二分)

2018-01-24 12:02 253 查看
/*

    hdu 4004

    题意大体是

    青蛙要过河,河上有n块石头,只能跳m下

    告诉你河宽L以及每块石头离开始的岸边的距离

    问青蛙至少要有跳多远的能力才能跳过去

    可以把对岸看成距离开始的岸边L远的一块石头

    需要跳到这块石头上去

    二分找到青蛙需要的最小的跳跃能力即可

*/

#include <iostream>

#include <stdio.h>

#include <string.h>

#include <math.h>

#include <algorithm>

using namespace std;

int L,n,m;

int s[500005];

int work(int x)//判断最多跳x远是否能跳过去

{

    if(x*m<L)//每一次的最远距离*次数<总距离,肯定是不行的

        return 0;

    int cnt=0;//记录在最多跳x的情况下,需要跳多少次

    int i=1,j=0;//表示i表示终点是那一块石头,j表示起点

    while(i<=n+1)//原本有n块石头,加上对岸

    {

        cnt++;

        if(x<s[i]-s[j])//如果最大跳跃能力<最近的两块石头的距离,肯定是不行的

            return 0;

        while(x>=s[i]-s[j]&&i<=n+1)//跳一下或许可以越过多块石头,以此来减少跳跃次数

            i++;

        j=i-1;//能跳到i-1跳不到i,所以下一次的起点为i-1

    }

    if(cnt>m)//如果跳到对岸的次数超过,题目给出的,肯定是不行的

        return 0;

    return 1;

}

int main()

{

    while(scanf("%d%d%d",&L,&n,&m)!=-1)

    {

        s[0]=0;

        s[n+1]=L;

        for(int i=1;i<=n;i++)

            scanf("%d",&s[i]);

        sort(s+1,s+1+n);

        int l=0,r=L,mid;

        while(r-l>1)//二分查找

        {

            mid=(l+r)/2;

            int w=work(mid);

            if(w)

                r=mid;

            else

                l=mid;

        }

        printf("%d\n",r);

    }

    return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: