河的长度为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 二分
时间: 2024-10-12 03:09:54