算法基础第一讲(二分)

1.2 二分

本次主要讲到整数二分和浮点数二分,整数二分要考虑到边界问题,浮点数二分较为容易,可以采用精度控制法和循环次数控制法。

1.2.1 整数二分

  • 二分和单调性的关系(有单调性的 一定可以二分)
  • 二分是确定区间上满足某个性质的边界点
  • 二分的模板是一定能找到解的
二分算法.png
//区间[l,r]被划分为[l, mid]和[mid + 1, r]时使用
int bsearsh_1(int l,int r)
{
    while(l < r)
    {
        int mid= l+r>>1;
        if(check(mid)) r = mid;
        else l = mid + 1;
    }
    return l;
}
//区间[l, r]被划分为[l, mid -1]和[mid, r]
int bsearch_2(int l,int r)
{
    while(l < r)
    {
        int mid = l+r+1>>1;
        if(check(mid)) l = mid;
        else r = mid -1;
    }
    return l;
}

步骤

  1. 先写check函数
  2. 看下l r 更新方式 如果是 l =mid (板子1 mid补上1) 否则是 r =mid
  3. 补上加1防止进入死循环
  • 习题 789 数的范围
#include<iostream>
using namespace std;
const int N=1e6+10;
int q[N];
int main()
{
    int n,m,x;
    scanf("%d %d",&n,&m);
    for(int i=0;i<n;i++){
        scanf("%d",&q[i]);
    }
    while(m--){
        scanf("%d",&x);
        int l=0,r=n-1,mid;
        while(l<r){
            mid=l+r>>1;
            if(q[mid]>=x) r=mid;
            else l= mid+1;
        }
        if(q[l]!=x)cout<<"-1 -1\n";
        else {
            cout<<l<<" ";
            int l=0,r=n-1,mid;
            while(l<r){
                mid=(l+r+1)>>1;
                if(q[mid]<=x) l=mid;
                else r =mid-1;
            }
            cout<<l<<endl;
        }
    }
}

1.2.2 浮点数二分

  • 不用考虑处理边界问题,较容易。
  • 经验值:误差区间比题目要求多乘10^{-2}
#include<iostream>
using namespace std;
const double t=1e-8;
int main()
{
    //cout<<t;
    double a,l=-10000,r=10000,mid;
    cin>>a;
    while((r-l)>t){
        mid=(l+r)/2;
        if(mid*mid*mid<=a) l=mid;
        else r=mid;
    }
    printf("%.6lf",l);
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。