首页 > 代码库 > hdu4004The Frog's Games 二分

hdu4004The Frog's Games 二分

河的长度为L, 有n个石头,最多跳m次,求青蛙最少至少能够跳多远的最小值。

二分,去年学过,好像也写过,今年还是不会,惭愧。

在两个石头的最大值和河的宽度L之间二分,每一次判断在当前mid下,可不可以到达对岸

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
using namespace std;
int a[500005],b[500005];
int main()
{
    int i,L,n,m;
    int mid,max_,le,ri;
    while(scanf("%d%d%d",&L,&n,&m)!=EOF)
    {
        for(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        a[n+1]=L;
        a[0]=0;
        sort(a,a+n+2);   /// 数据不是依次给的 所以要先排序
        max_=0;           /// 两个石头的最大距离
        for(i=1;i<=n+1;i++){
            b[i]=a[i]-a[i-1];   ///求从开始的岸边开始,每连个点的距离,一共有n+1个
            if(max_<b[i])
                max_=b[i];
        }
        if(m>n){              /// if m>n 即每次都依次跳到下一个石头就可以保证到达对岸, 此时输出max_
            printf("%d\n",max_);
            continue;
        }
        le=max_;
        ri=L;
        int cnt=0,t;
        while(le<=ri){   /// 二分

              t=mid=(le+ri)/2;///步数
              cnt=0;    /// 走的
              i=1;       /// 走到第n个石头
              while(cnt<=m&&i<=n+1){  /// 能力为mid时,判断可不可以跳过
                 t=mid;
                 while(i<=n+1&&b[i]<=t)  /// 一次最多跳到哪个石头上,
                    t-=b[i++];    
                 cnt++;
              }
              if(cnt<=m&&i>n+1) ri=mid-1; /// 跳过了 ,说明mid大了,将ri=mid-1;
              else le=mid+1;
        }
        printf("%d\n",le);

    }
    return 0;
}


hdu4004The Frog's Games 二分