HDU4004 The Frog's Games (二分+贪心)

这里写图片描述
这里写图片描述

题意:青蛙通过河中央的n块石头过河, 所有石头均在与河岸垂直的一条线上,给定每块石头到河岸的距离,给出河的宽L,给定青蛙跳的次数上限m(即青蛙必须经过m或小于m次跳动,过到河对岸),求出青蛙能够过河的最小步长。
当步长为河宽时,青蛙必能跳过,二分步长,求最小步长。

#include<iostream>
#include<cstring>
#include<algorithm>
#define maxn 500010
using namespace std;
int l,n,m;  //河的宽度,n块石头,最多跳n步 
int stone[maxn];

int pd(int jump){
    int cnt=0,i=0;
    if(m*jump<l) return false;

    for(int j=1;j<=n+1;j++)
        if(stone[j]-stone[i]>jump)
            if(j==i+1) return false;    //出现相邻的石子距离大于步长 
            else {
                i=(--j);    //下次操作j++,此时的i记录需要跳的位置 
                cnt++;       
            }
    if((++cnt)>m) return false; //跳过河的最后一步没有记录,所以cnt++; 
    return true;
}

int main(){
    while(cin>>l>>n>>m){
        memset(stone,0,sizeof(stone)); 
        for(int i=1;i<=n;i++)
            scanf("%d",&stone[i]);
        stone[n+1]=l;  //最后还得跳上岸
        sort(stone+1,stone+n+1);

        //二分步长
        int low=0,high=l;
        int mid;
        while(low<=high){
            mid=(high+low)/2;
            if(pd(mid)) high=mid-1;
            else low=mid+1;
        }
        cout<<low<<endl;
    //  cout<<mid<<endl;
    }
    return 0;
} 

猜你喜欢

转载自blog.csdn.net/qq_37360631/article/details/80146646