1650: [Usaco2006 Dec]River Hopscotch 跳石子

题目:数轴上有n个石子,第i个石头的坐标为Di,现在要从0跳到L,每次条都从一个石子跳到相邻的下一个石子。现在FJ允许你移走M个石子,问移走这M个石子后,相邻两个石子距离的最小值的最大值是多少。

输入:25 5 2(l m n)
2(d[i])
14
11

21
17

输出:4

解析:二分枚举两个石头间的最小值x,如果有哪两块石头之间的距离小于x,就删除后面这块石头。做完后,如果删除的石头数量小于等于限定数量,则成立,否则,不成立。

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long p1,m,mid,l,ans,n,l1[50001],d[50001],l2[50001],lef,righ;
bool check(long long x)
{
  long long k1,k2;
  if (x>l) return false;
  k1=m;
  p1=0;
  for (int i=1;i<=n+1;++i)
  {
      if (d[i]-d[p1]<x) k1-=1;
      else p1=i;
  }
  k2=m;
  p1=n+1;
  for (int i=n;i>=0;--i)
  {
      if (d[p1]-d[i]<x) k2-=1;
      else p1=i;
  }
  if ((k1>=0)||(k2>=0))  return true;
  else return false;
}
int main()
{
  cin>>l>>n>>m;
  for (int i=1;i<=n;++i) cin>>d[i];
  d[0]=0;
  sort(d+1,d+1+n);
  d[n+1]=l;
  lef=0;
  righ=l+3;
  while (lef<=righ)
  {                                                                                                                                       
   mid=(lef+righ)/2;
   if (check(mid)==true) 
   {
       lef=mid+1;
       if (mid>ans) ans=mid;
   }
   else righ=mid-1;
  }
  cout<<ans<<endl;
  return 0;
}

ps:本人代码较繁,建议参考更简洁的代码。

原文地址:https://www.cnblogs.com/2014nhc/p/6207800.html