HDU4004The Frog's Games二分!二分!

来源:互联网 发布:暴风雨加密软件 编辑:程序博客网 时间:2024/05/16 00:26

题目在此

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

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

#include <iostream>#include<cstdio>#include<cmath>#include<algorithm>using namespace std;#define N 500005int 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;}


原创粉丝点击