首页 > 编程语言 >二分——acwing算法基础课笔记

二分——acwing算法基础课笔记

时间:2023-12-08 20:11:26浏览次数:43  
标签:二分 int void mid else while stp 基础课 acwing

个人笔记,欢迎补充、指正。

此次完全以个人理解来写。

整数二分

 整数二分有两种,分别是找左边界和找右边界。

 寻找符合要求的左边界:绿色点

int bsearch_1(int l, int r)
{
    while (l < r)
    {
        int mid = l + r >> 1;//对应下界,最左
        if (check(mid)) r = mid;
        else l = mid + 1;
    }
    return l;
}

寻找符合要求的右边界:红色点

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

和例题789. 数的范围 - AcWing题库结合看很容易理解

主要要确定check条件

此题

#include<bits/stdc++.h>

using namespace std;

void func(void);

const int N = 1e5 + 10;

int n,t,ans,stp;
int a[N];

int main(void)
{
    cin >> n >> t;
    for(int i=0;i<n;++i)    cin >> a[i];
    while(t--)
    {
        cin >> stp;
        int l = 0,r = n - 1;
        while(l < r)
        {
            int mid = l + r >> 1;
            if(a[mid] >= stp)    r = mid;
            else                l = mid + 1;
        }
        if(a[l] != stp)    cout << "-1 -1\n";
        else
        {
            cout << l << ' ';
            int l = 0,r = n - 1;
            while(l<r)
            {
                int mid = l + r + 1 >> 1;
                if(a[mid] <= stp)    l = mid;
                else                r = mid - 1;
            }
            cout << l << '\n';
        } 
    }
    return 0;
}

#include<bits/stdc++.h>

using namespace std;

void func(void);

const int N = 1e5 + 10;

int n,t,ans,stp;
int a[N];

int main(void)
{
    cin >> n >> t;
    for(int i=0;i<n;++i)    cin >> a[i];
    while(t--)
    {
        cin >> stp;
        int l = 0,r = n - 1;
        while(l < r)
        {
            int mid = l + r >> 1;
            if(a[mid] < stp)    l = mid + 1;
            else            r = mid;
        }
        if(stp != a[l])    cout << "-1 -1\n";
        else
        {
            cout << l << ' ';
            int l = 0,r = n - 1;
            while(l < r)
            {
            int mid = l + r + 1 >> 1;
            if(a[mid] > stp)    r = mid - 1;
            else            l = mid;
            }
            cout << l << '\n';
        }

    }
    return 0;
}

改变了check条件,但是都可ac

 

浮点数二分

浮点数二分就简单多了

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

 

标签:二分,int,void,mid,else,while,stp,基础课,acwing
From: https://www.cnblogs.com/zerocloud01/p/17872621.html

相关文章

  • Acwing 840. 模拟散列表
    题面:维护一个集合,支持如下几种操作:Ix,插入一个整数 \(x\);Qx,询问整数 \(x\) 是否在集合中出现过现在要进行 \(N\) 次操作,对于每个询问操作输出对应的结果。原题链接:840.模拟散列表-AcWing题库哈希表[1]基本概念哈希表也叫散列表,通过将键映射到索引位置(在关键......
  • 二分图的匹配
    定义有点扩展域并查集的意思~如果一张无向图的\(N\)个节点\((n\geq2)\)可以分成\(A,B\)两个非空集合,其中\(A\capB=\emptyset\),并且在同一集合内的点之间都没有边相连,那么称这张无向图为一张二分图。\(A\)、\(B\)分别称为二分图的左部和右部。性质如果两个集......
  • AcWing 802. 区间和
    题面:假定有一个无限长的数轴,数轴上每个坐标上的数都是\(0\)。现在,我们首先进行\(n\)次操作,每次操作将某一位置\(x\)上的数加\(c\)。接下来,进行\(m\)次询问,每个询问包含两个整数\(l\)和\(r\),求出在区间\([l,r]\)之间的所有数的和。原题链接:802.区间和-AcW......
  • 59AcWing 840. 模拟散列表
    点击查看代码#include<iostream>#include<cstring>usingnamespacestd;constintN=200003,null=0x3f3f3f3f;inth[N];intfind(intx){intk=(x%N+N)%N;//索引while(h[k]!=null&&h[k]!=x){k++;if(k==N)k=0;//重新搜索......
  • 刷题 二分
    2023.12.6cf1902B二分一般来讲我们会在以下情况用到二分:求单调函数的零点求最小值的最大,或最大值的最小很难直接算出答案,但是很好判定答案合不合法二分答案和二分查找差不多,就是check函数内是贪心dp之类的东西当用二分控制精度时,以r-l>eps为循环条件,mid选r和l都行,一般需......
  • Acwing 5367. 不合群数
    题面:如果一个正整数无法被 \([2,a]\) 范围内的任何整数整除,则称其为不合群数。请你计算并输出 \([2,b]\) 范围内的最大不合群数。提示:\(10\) 亿内的最大质数是 \(999999937\),且相邻质数之间的差值均不超过 \(300\)原题链接:5367.不合群数-AcWing根据给出的提示判......
  • Note - 整体二分
    其实是做题做不动了然后也不想卷whk于是跑来写这个。正式完工估计要咕咕咕了。多组询问,对于单组询问可以二分,但是每组暴力二分又会T,而且又可以离线,修改可以根据\(mid\)分到某一边,修改对询问的贡献有结合律、交换律时,可以考虑整体二分。即定义函数\(solve(l,r,pt)\)表......
  • AcWing 1205. 买不到的数目
    题面:水果糖被包成\(n\)颗一包和\(m\)颗一包的两种,用这两种包装来组合,不能拆包卖。在\(4\)颗一包和\(7\)颗一包的情况下,最大不能买到的数量是\(17\)。本题的要求就是在已知两个包装的数量时,求最大不能组合出的数字。原题链接:1205.买不到的数目-AcWing数论:组合......
  • ACwing342. 道路与航线
    这道题是把拓扑排序和迪杰斯特拉交叉进行。#include<iostream>#include<stdio.h>#include<algorithm>#include<cstring>#include<queue>#include<vector>usingnamespacestd;typedefpair<int,int>PII;constintN=25005,M=50......
  • AcWing 836. 合并集合
    题面:一共有 \(n\) 个数,编号是 \(1∼n\),最开始每个数各自在一个集合中。现在要进行 \(m\) 个操作,操作共有两种:1、Mab,将编号为 \(a\) 和 \(b\) 的两个数所在的集合合并,如果两个数已经在同一个集合中,则忽略操作;2、Qab,询问编号为 \(a\) 和 \(b\) 的两个数是否在......