二分总结

整数二分模板

bool check(int x) {/* ... */} // 检查x是否满足某种性质

// 区间[l, r]被划分成[l, mid]和[mid + 1, r]时使用:
int bsearch_1(int l, int r)
{
    while (l < r)
    {
        int mid = l + r >> 1;
        if (check(mid)) r = mid;    // check()判断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;
}

浮点数二分模板

bool check(double x) {/* ... */} // 检查x是否满足某种性质

double bsearch_3(double l, double r)
{
    const double eps = 1e-6;   // eps 表示精度,取决于题目对精度的要求
    while (r - l > eps)
    {
        double mid = (l + r) / 2;
        if (check(mid)) r = mid;
        else l = mid;
    }
    return l;
}

789. 数的范围

https://www.acwing.com/problem/content/791/

#include <iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
int n,q;
int a[100005],b[10005];
//题意在数组中查找某元素,找不到就输出-1,找到了就输出不小于该元素的最小位置和不大于该元素的最大位置。
//不小于
int fun1(int l,int r,int k){
    while(l<r){
        int mid=l+r>>1;
        if(a[mid]<k) l=mid+1;
        else r=mid;
    }
    if (a[l]!=k) return -1;
    return l;
}
//不大于
int fun2(int l,int r,int k){
    while(l<r){
        int mid=l+r+1>>1;
        if(a[mid]>k) r=mid-1;
        else l=mid;
    }
    if (a[l]!=k) return -1;
    return l;
}
int main(){
    cin>>n>>q;
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    for(int i=0;i<q;i++){
        cin>>b[i];
    }

    for(int i=0;i<q;i++){
        cout<<fun1(0,n-1,b[i])<<" "<<fun2(0,n-1,b[i])<<endl;
    }
  return 0;
}

790. 数的三次方根

https://www.acwing.com/problem/content/description/792/

/*
double bsearch_3(double l, double r)
{
    const double eps = 1e-6;   // eps 表示精度,取决于题目对精度的要求
    while (r - l > eps)
    {
        double mid = (l + r) / 2;
        if (check(mid)) r = mid;
        else l = mid;
    }
    return l;
}
*/
#include <iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<cstring>
using namespace std;
double n;
double fun(double l,double r){
    const double eps=1e-8;//一般比题目多后两位比较稳
    while(r-l>eps){
        double mid=(l+r)/2;
        if(mid*mid*mid<=n) l=mid;
        else r=mid;
    }
    return l;
}
int main(){
    cin>>n;
    printf("%.6lf\n", fun(-100.0,100.0));
  return 0;
}
//  freopen("testdata.in", "r", stdin);

posted @ 2021-03-23 14:44  一个经常掉线的人  阅读(40)  评论(0)    收藏  举报