C语言排序(5)___青蛙过河——(二分查找)

来源:互联网 发布:淘宝图片尺寸和大小 编辑:程序博客网 时间:2024/05/14 12:25

Description

The annual Games in frogs' kingdom started again. The most famous game is the Ironfrog Triathlon. One test in the Ironfrog Triathlon is jumping. This project requires the frog athletes to jump over the river. The width of the river is L (1<= L <= 1000000000). There are n (0<= n <= 500000) stones lined up in a straight line from one side to the other side of the river. The frogs can only jump through the river, but they can land on the stones. If they fall into the river, they 
are out. The frogs was asked to jump at most m (1<= m <= n+1) times. Now the frogs want to know if they want to jump across the river, at least what ability should they have. (That is the frog's longest jump distance).

Input

The input contains several cases. The first line of each case contains three positive integer L, n, and m. 
Then n lines follow. Each stands for the distance from the starting banks to the nth stone, two stone appear in one place is impossible.

Output

For each case, output a integer standing for the frog's ability at least they should have.

Sample Input

6 1 2225 3 311 218

Sample Output

411

样例:

#include <stdio.h>int arr[500050],len,m,n;          //n个石头坐标、河的总宽、最多跳的次数、石头个数int seeing(int x)                //参数x表示跳远能力,此函数判断当前能力是否能够过河{int now=0;           //now变量表示当前你的坐标.int i=0;            //所处的石头序号.int times=0;        //跳的次数while(times<m)     //当跳的次数不满最大m次的时候继续{while(arr[i]-now<=x&&i<=n)   //i递增.直到目标石头与当前位置的距离超过跳跃能力,i++;                now=arr[i-1];     //青蛙跳到这个石头,把当前坐标更新到石头坐标.times++;        //跳跃次数加1}if(now==len)            //m次跳跃后判断青蛙是否已经到了对岸return 1;       //返回1表示最小能力值可能比当前能力值小.elsereturn 0;       //返回0表示最小能力值一定比当前能力值大.}int bin(int l,int r)        //此函数是用二分查找来枚举可能的能力值{int mid;        //二分查找的中间值while(l<r)          //二分查找的结束标准是左右界限相等或对调.{mid=(l+r)/2;          //令mid为左右界限的中间值 if(seeing(mid)!=0)      //调用seeing函数判断当前能力值是否可以过河r=mid;    //如果能,把右边界调整为中间值.elsel=mid+1;    //如果不能,把左边界调整为中间值+1 
}                   //以上调整产生差异的原因是因为seeing函数返回值的意义一个是可能,一个是一定(见上).return r;         }void quicksort(int left,int right)   //定义的石块坐标排序的快排{int i,j,step;i=left,j=right,step=arr[left];if(i>j)return;while(i!=j){while(i<j&&arr[j]>=step)j--;while(i<j&&arr[i]<=step)i++;if(i<j)arr[i]^=arr[j]^=arr[i]^=arr[j];}arr[left]=arr[i],arr[i]=step;quicksort(left,i-1);quicksort(i+1,right);}int main(){int i;while(scanf("%d%d%d",&len,&n,&m)!=EOF)   //输入河的宽度、石头个数、最多跳的次数{for(i=0;i<n;i++)scanf("%d",&arr[i]);   //循环存储石头坐标arr[n]=len;                 //因为终点可以落脚.所以终点可以看作最后一个石头.quicksort(0,n);            //石头坐标排序.int max=arr[0];            //以下四排.目的找出相邻两个石头的最大距离,即使找出跳跃能力的下界.for(i=0;i<n;i++)   if(arr[i+1]-arr[i]>max)max=arr[i+1]-arr[i];printf("%d\n",bin(max,len));     }return 0;}

题目大概意思:

对于每组输入数据:

第一排 分别是  河的宽度、石头的个数n、最多的跳跃次数.

以下n排是n个石头的坐标,

然后要求在最多跳跃次数以内,每次落地只能在石头上,跳到河的对岸.输出青蛙至少有每次跳多远的能力?



这道题目坑点:

1.题目输入数据的石头坐标可能不是按照从小到大排序,所以要定义快排排序.


本题主要是用的二分查找枚举,利用seeing函数巧妙判断.


1 0
原创粉丝点击