题目传送门: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 ",left); 42 } 43 return 0; 44 }