hdu 4004 贪心 二分查找

来源:互联网 发布:淘宝店铺可以转吗 编辑:程序博客网 时间:2024/06/08 04:20

                                       HDU 4004

题目大意:

有一条河,宽为L,河里有N个石墩,第i个石墩距离河东岸为ai。现在有一只青蛙,要从河东岸跳到河西岸。青蛙可以一步跳到终点,也可以跳到石墩上,但是只能跳M次。然后问,

青蛙至少要跳多大的距离才能保证在跳不超过M次后跳到终点。


大致思路:

这实际是一个线性问题,一般的线性问题都可以用二分来解决。对于这道题,我们可以知道青蛙最坏情况下是直接一步跳到终点(其实只有m为1的时候)。那我们可以以L为上界初始值,以0为下界初始值。然后不断的二分查找,当上界和下界相等时,就是我们要求的答案。

而当我们试探跳mid步((上界+下界 )/2)是否可以在不超过M次到达终点时,也是有讲究的。我是贪心的试探,也就是对于第一个石墩,如果青蛙可以以mid步到达,那我们就看第二个石墩,如果第二个也可以,我们就看第三个。。。假如当跳第k个石墩时,青蛙跳不到。那我们可以看它的前一个石墩(因为之前的都可以跳到)。如果第k-1个石墩距离第k个石墩的距离还大于mid时,那青蛙就无法跳到终点了。

以上面的方法来看,当青蛙跳到终点了,那我们还要看跳的次数是否大于m,大于就不行。小于等于的话代表mid是个待定的可行解。。。

代码:

#include<stdio.h>#include<iostream>#include<algorithm>using namespace std;int n,l,m;int a[500005];int cha(int x){    int cot=0;    int len=0;//记录青蛙此时的位置距离起点的距离,初始时青蛙在起点,len为0    int i;    for(i=1;i<=n+1;i++)    {        if(a[i]-len<=x)continue;//能跳到,我们就看下一个。        if(i==1)return 0;//如果第一个石墩就到达不了,那无法到达终点        if(a[i]-a[i-1]>x)return 0;//让青蛙跳到第a[i-1]号石墩,然后看下一块石墩与此时距离是否大于x步,大于就跳不了。。        len=a[i-1];//青蛙已经在第a[i-1]号石墩了        cot++;//跳的次数加1    }    if(len!=a[n+1])cot++;//因为当我们每次判断第a[i]号石墩时,青蛙都不在这个石墩上,所以还要跳一步到达终点。    if(cot>m)return 0;    return 1;}int main(){    while(~scanf("%d%d%d",&l,&n,&m))    {        for(int i=1;i<=n;i++)        {            scanf("%d",&a[i]);        }        a[n+1]=l;//这是L        sort(a+1,a+n+2);//题目输入没保证数据是从小到大的,我们要排个序,青蛙依次跳。        int left=0;        int right=l;//L        int ans=0;        while(left<=right)        {            int mid=(right+left)>>1;            if(cha(mid))//看mid是否是可行解            {                right=mid-1;//是的话,缩小范围,因为答案是最小的步数。                ans=mid;            }            else                left=mid+1;//不是的话,往上找        }        printf("%d\n",ans);    }}

***********************************************************************************************************************************

原创粉丝点击