P1824 进击的奶牛——洛谷(二分)

二分的模板

找到满足某个性质的最大值

int search(int l, int r)
{
   while(l < r)
   {
      int mid = l + r + 1 >> 1;
      if(check(mid)) l = mid;
      else r = mid - 1;
   }
   return l;
 }

找到满足某个性质的最小值

int search(int l, int r)
{
   while(l < r)
   {
      int mid = l + r  >> 1;
      if(check(mid)) r = mid;
      else l = mid + 1;
   }
   return l;
 }

进击的奶牛

P1824 进击的奶牛——洛谷(二分)_第1张图片

题意:把牛分别放在不同的牛棚当中,有很多种放的方法,每种方法中牛之间有一个最小距离;
题目要求的是这些方法当中最小距离的最大值。

题目要求:“相邻两头牛最小距离”的最大值

解题步骤:1、确定最小距离的范围(1 ~ 第一个牛栏到最后一个牛栏的距离)
2、二分枚举最小距离
3、检验此最小距离是否可行
4、通过检验结果确定下一次枚举范围

#include 
#include  //需要sort
using namespace std;
int n, m, a[100001];
bool f(int x); 
int main()
{
       scanf("%d%d", &n, &m) ;
        for (int i = 1; i <= n; ++i)
            scanf("%d", &a[i]);
        sort(a + 1, a + n + 1); //排序,从样例就可以看出来不是有序的
        int l = 0, r = 1000000; //不用管初始值,能AC就是了
        while (l + 1 < r) //二分
        {
            int mid = l + r >> 1; //二分区间
            if (f(mid)) l = mid; //判断可取
            else r = mid;
        }
        printf("%d\n", l); //l就是答案
}
bool f(int x)
{
    int x1 = a[1], cnt = 1; //首先第一个隔间肯定是要放牛的.
    for (int i = 2; i <= n; ++i) //循环接下来每一个隔间
        if (a[i] - x1 >= x) //如果能放下
        {
            ++cnt; //又放进了一头牛
            x1 = a[i]; //更新上一头牛的位置
            if (cnt == m) return 1; //循环里return
        }
    return 0; //无法实现
}

你可能感兴趣的:(算法习题)