青蛙过桥

来源:互联网 发布:好看的文学小说知乎 编辑:程序博客网 时间:2024/03/29 18:10

                                                                         青蛙过河  

        这是一道曾经做过的题目,那场比赛做的我超级郁闷,水题也没刷出来,全都坑在这一题上了(谁让咱太水了)。记得第一次见这一题时,我的思路是这样的:1 2 3 4 5 6 7 8……假如它们代表石头,我先算出隔去第一块石头的跳跃距离,然后第二块,依此类推,从中找出最小的,这样就隔去了一块石头,等隔去的石头符合要求了,再找两个石头之间的最大值,这个值就是对青蛙跳跃能力的最小要求。比赛时,我一直纠结于超时,所以没写,所以最后连超时都没看到,就结束了。比赛结束后,写了一次,果真超时,呵呵。

     昨天下午才把这题给A了,其实这道题的程序,基本是我抄别人的了,问一同学这一题怎么做(比赛结束时,他告诉我用二分,我怎么也没搞明白怎么用二分),他说他博客里有,那就看他的博客呗,呵呵。在这里,只能说说我对这道题的理解了。

这一题时通过假设青蛙的跳跃能力来进行判断的,二分是对青蛙跳跃能力的二分。 跳跃的次数,是个限制,青蛙的跳跃能力一定在0到L(L代表河岸之间的距离)之间,那么我们假设(r=0,l=L),青蛙的跳跃能力,为mid=(r+l)/2,看看青蛙能否在满足步数的情况下能否成功过河,如果能跳过,l=mid,接着假设青蛙的跳跃能力为mid=(l+r)/2……如果不能,l=mid+1;接着假设青蛙的跳跃能力为mid=(l+r)/2……结束条件为r=l.

  #include<stdio.h>#include<algorithm>using namespace std;#define N 500005 int pos[N];int  L,n,m;bool across(int l){int step=0,cur=0,i;for(i=0;i<=n;){if(++step>m||pos[i]-cur>l)return false;while(pos[i]-cur<=l&&i<=n) i++;cur=pos[i-1];}return true;}int main(){while(scanf("%d%d%d",&L,&n,&m)!=EOF){int i,mid;for(i=0;i<n;i++)scanf("%d",&pos[i]);pos[n]=L;sort(pos,pos+n);int l=0,r=L;while(l<r){mid=(l+r)/2;if(across(mid))r=mid;else   l=mid+1;}printf("%d\n",r);}}                


原创粉丝点击