二分算法学习(愤怒的牛+解题思路)

一、适用范围

        二分算法的基本用途是在单调序列或单调函数中做查找操作,因此问题的答案具有单调性的时候,我们就可以通过二分把求解转换为判定。

        二分算法的思想是不断将待求解区间平均分成两份,根据求解区间中点的情况来确定目标元素所在的区间,这样就把解的范围缩小一半。

二、代码实现

1、整数二分:

int erfen(int l,int r)
{
     int ans;
     while(l<=r){
         int mid = (l+r)>>1;
         if(check(mid)){//判断一下是否满足条件
            ans = mid;
            l = mid + 1;
         }
         else
            r = mid - 1;
     }
     return ans;
}

2、实数二分

double erfen(double l,double r)
{
    double mid;
    while(fabs(l-r)>0.01){//0.01是题目中精度要求,
        mid = (l+r)/2.0;//浮点型数据作比较要注意其精度问题
        if(check(mid))
            r = mid;
        else
            l = mid;
    }
    return l;
}

三、例题

                                                     愤怒的牛

题目描述

农夫约翰建造了一座有  间牛舍的小屋,牛舍排在一条直线上,第  间牛舍在  的位置,但是约翰的  头牛对小屋很不满意,因此经常互相攻击。约翰为了防止牛之间互相伤害,因此决定把每头牛都放在离其它牛尽可能远的牛舍。也就是要最大化最近的两头牛之间的距离。

牛们并不喜欢这种布局,而且几头牛放在一个隔间里,它们就要发生争斗。为了不让牛互相伤害。John 决定自己给牛分配隔间,使任意两头牛之间的最小距离尽可能的大,那么,这个最大的最小距离是多少呢?

输入格式

第一行用空格分隔的两个整数  和 ;

第二行为  个用空格隔开的整数,表示位置 。

输出格式

输出仅一个整数,表示最大的最小距离值。

样例

样例输入

5 3
1 2 8 4 9

样例输出

3

做题思路:

        题目要求寻找最小的间隔距离,类似求最值问题,二分可以很好的解决。

        1、对牛舍的位置x进行排序

        2、将第一头牛放进第一间牛舍

        3、运用二分的方法去判断一个距离,每个求出的值,都需要去验证是否满足条件,直到二分算法结束,得出最佳距离。

例题地址:https://loj.ac/problem/10011

AC代码

#include<bits/stdc++.h>

using namespace std;
int a[100005];
int n,m;

int check(int d)//判断一下此间隔是否适用
{
    int sign = d+a[1];
    int sum = 1;
    for(int i=2;i<=n;i++){
        if(a[i]<sign)
            continue;
        sign = a[i]+d;
        sum++;
    }
    return sum>=m;
}
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=a[n]-a[1],mid;
    while(l<=r){//二分查找最小的间隔
        mid = (r+l)>>1;
        if(check(mid))
            l = mid+1;
        else
            r = mid-1;
    }
    printf("%d
",r);
    return 0;
}

一天终将过去,你能留下什么。 

原文地址:https://www.cnblogs.com/codepeanut/p/12920501.html