进击的奶牛

题目大体意思:有n头牛,你需要在其中选c头,使得这c头牛最近的2头牛之间的的距离最远,输出最近的最远距离
我们可以从最大距离和最小距离之间选择一个最大的可实现距离,因为数据过大,无法顺序选择,只有通过二分可以实现:先二分找一个距离,若这个距离可以实现,则用变量替换此数(注意不用比较,因为二分得到的答案一定是更优更大的),就往更大的距离去寻找,若这个距离不可以实现,就往更小的距离去找,重复寻找,直到区域区间之内没数为止。

#include<iostream>
#include<cstdio> 
#include<cstring>
#include<algorithm>
using namespace std;
int A[1000010];
int n,c,a;
bool check(int x)//判断此答案是否可行 
{
    int num = 0;
    int l = A[1];//l记录上一只牛的位置,开始时第一只牛一定在第一个牛栏 
    for(int i = 2; i <= n;i ++)//依次枚举每个牛栏 
    {
        if(A[i] - l < x) num ++;//若此距离不满足当前答案,那么需要的牛栏数+1,即把当前牛放到下一个牛栏 
        else l = A[i];//否则就更新上一次的牛栏位置 ,即上一头牛放的位置 
        if(num > a) return false;// 若需要牛栏数大于最大牛栏数,此答案不可行 
    }
    return true;//反之,若需要牛栏数小于最大需要牛栏数,此答案可行
}
int main()
{ 
  scanf("%d%d",&n,&c);
  for(int i = 1;i <= n;i ++)
    scanf("%d",&A[i]);
  sort(A + 1,A + n + 1);//由于无序,需排序(sort默认从小到大,不用写规则) 
  a=n-c;//最大剩余牛栏数 
  int l = 1;//二分的左界,从1开始,即可能情况的最小值 
  int r = A[n] - A[1];//二分右界,即可能情况的最大值 
  while( l+1 < r )//若左<右,则继续二分答案 
  {
      int mid = (l + r)/2;//二分 两区间分别为l ~ mid    ,     mid ~ r;
      if(check(mid)) l = mid;//若此答案可行,从mid ~ r区间继续查找(更大答案),即修改左界l=mid 
      else r = mid;//反之,若此答案不可行,从l ~ mid区间查找(合理答案),即修改左界l=mid 
  }
  if(check(r)) printf("%d",r);//若可行解为右界,输出右界 
  else printf("%d",l);//若可行解为左界,输出左界 
  return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值