zoukankan      html  css  js  c++  java
  • 二分算法学习(愤怒的牛+解题思路)

    一、适用范围

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

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

    二、代码实现

    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;
    }
    

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

  • 相关阅读:
    Android SDK manager 无法更新解决方法
    platform_set_drvdata的源码分析
    从一个男人身上看出他的修养和抱负
    更换RAID1硬盘过程记录
    无线路由器连接有线路由器设置
    在ASP.NET下实现数字和字符相混合的验证码 (转载)
    不走寻常路 设计ASP.NET应用程序的七大绝招
    .NET 2005 使用MasterPages实现Web窗体模板
    用Visual C# 实现四则混合运算(转载)
    如何实施好CRM (转载)
  • 原文地址:https://www.cnblogs.com/codepeanut/p/12920501.html
Copyright © 2011-2022 走看看