备战蓝桥杯---二分(基础)

本文详细介绍了二分查找的工作原理,强调了代码实现中的模板分析和易错点,以及C++STL中`binary_search`、`lower_bound`和`upper_bound`函数的应用。通过实例演示如何避免死循环并优化二分查找算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

何为二分?形象的说,就是单调函数求零点。

我们先对二分查找简单的分析一下(主要是模板及易错点)

1.找>=x的第一个位置:                 2.找<=x的第一个位置:                                         

while(l<r){                                         while(l<r){

mid=(l+r)/2;                                        mid=(l+r)/2;

if(a[mid]>=x) r=mid;                            if(a[mid]<=x) l=mid;

else l=mid+1;                                      else r=mid-1;}

}

首先,对于代码1,当mid的值大于等于x时,说明mid后面都不是目标值但自己不确定。

而当mid的值小于x时,说明mid自己及其前面都不是目标值。

所以l到r的区间即为目标值存在的区间,所以只要保证两者稳定的逼近一个点即可。

当区间不断变小时,对于代码2,因为mid的向左取整,而l又直接赋值为mid,于是可能会进入死循环。而1的话l再mid基础上加了1,保证它至少会走1步,避免了死循环。

所以代码2只需mid=(l+r+1)/2即可。或者把循环条件改为l<=r,l=mid+1;这样就能保证不会陷入死循环,不过这样答案在l-1上。

因此,法1可以改成:l<=r,r=mid-1;

这样子,r及其后面一个都可能为答案,而终止时l==r+1;因此l所在的地方即为答案。

特别的当r不动时,l一定与R会相等,如果此时r还是不动,说明无法找到,l也指向右边界+1;

注意一点细节:

有时+r可能会超int ,我们可以用l+(r-l)/2来代替。

C++ STL的二分查找函数:

binary_search:返回bool是否存在

lower_bound:返回第一个符合条件的位置 1 2 3 5 6 7,搜4时指向5

upper_bound:返回最后一个符合条件的位置 1 2 2 3 3 5,插3时指向5

下面来一道水题:

我们用前缀和维护并分别用二分即可,下面是AC代码:

### 蓝桥杯竞赛必备知识点详解 #### 数据结构基础 数据结构是编程比赛中不可或缺的一部分。对于蓝桥杯而言,掌握基本的数据结构如数组、链表、栈和队列至关重要[^1]。这些结构不仅用于存储数据,还能够通过特定的操作来解决问题。 #### 算法设计技巧 算法效率直接影响程序运行时间,在蓝桥杯中尤为重要的是理解并能灵活运用经典算法,比如排序算法(快速排序、归并排序)、查找算法二分查找),以及动态规划等高级方法。此外,贪心策略也是解决某些优化类问题的有效手段之一。 #### 编程语言特性 熟悉所使用的编程语言是非常必要的。无论是C++还是Python,了解其语法细节可以帮助编写更高效简洁的代码。例如,在处理字符串时利用内置函数可以大大简化逻辑;而面向对象特性的合理应用则有助于构建复杂系统的模型。 #### 数学基础知识 离散数学中的组合计数原理、概率论初步概念都是常见的考点。另外还包括简单的图论知识,像最短路径计算(Dijkstra/Floyd-Warshall),最小生成树(Prim/Kruskal)等问题也经常出现在试题当中。 ```cpp // C++实现Dijkstra算法求解单源最短路径 #include <vector> #include <queue> using namespace std; const int INF = 0x3f3f3f3f; struct Node { int id, dist; bool operator<(const Node& rhs)const {return this->dist > rhs.dist;} }; void dijkstra(int start, vector<vector<pair<int,int>>>& adjList, vector<int>& minDist){ priority_queue<Node> pq; vector<bool> visited(adjList.size(), false); fill(minDist.begin(), minDist.end(), INF); // 初始化距离为无穷大 minDist[start]=0; // 起始节点到自身的距离设为0 pq.push({start, 0}); while(!pq.empty()){ auto curNode=pq.top(); pq.pop(); if (visited[curNode.id]) continue; visited[curNode.id]=true; for(auto edge : adjList[curNode.id]){ if (!visited[edge.first] && minDist[curNode.id]+edge.second<minDist[edge.first]){ minDist[edge.first]=minDist[curNode.id]+edge.second; pq.push({edge.first,minDist[edge.first]}); } } } } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值