题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=4004

题目意思是青蛙要过河,现在给你河的宽度,河中石头的个数(青蛙要从石头上跳过河,这些石头都是在垂直于河岸的一条直线上)

还有青蛙能够跳跃的 最多 的次数,还有每个石头离河岸的距离,问的是青蛙一步最少要跳多少米可以过河》

这是一道二分加贪心的题,从0到的河宽度开始二分,二分出一个数然后判断在这样的最小步数(一步跳多少距离)下能否过河

判断的时候要贪心

主要难在思维上,关键是要想到二分上去,能想到二分code就很好写了(实验二分的思维还是很强大的)

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 //typedef long long ll;
 5 int l,n,m;
 6 int num[500001];
 7 int check(int x)
 8 {
 9     if (x*m<l) return 1; //能过河的步数必然是大于平均值的
10     int i=1,j=0,step=0;
11     while (i<=n+1)
12     {
13         step++;
14         if (num[i]-num[j]>x) //不能满足相邻的两个石头之间的跳跃显然是不行的
15             return 1;
16         while (num[i]-num[j]<=x&&i<=n+1)//尽量使这一步能跳过更多的石头,贪心基本上都是这个格式
17             i++;
18         j=i-1;
19     }
20     if (step>m)  return 1; //判断是否超过规定的次数
21     return 0;
22 }
23 int main()
24 {
25     int left,right,i,mid;
26     while (~scanf("%d %d %d",&l,&n,&m))
27     {
28         for (i=1;i<=n;i++)
29            scanf("%d",&num[i]);
30         sort(num+1,num+1+n);
31         num[0]=0;num[n+1]=l;
32         left=0;right=l;
33         while (left<=right) //二分出最小步数
34         {
35             mid=(left+right)/2;
36             if (check(mid)) 
37                 left=mid+1;
38             else
39                 right=mid-1;
40         }
41         printf("%d\n",left);
42     }
43     return 0;
44 }

 

posted on 2015-07-24 18:41  蜘蛛侦探  阅读(1070)  评论(0编辑  收藏  举报