作为一名编程小白,我还是第一次写这种解释呢(以前写的都是题解QAQ)
咳咳,言归正传,我们今天来讲讲二分那些事
二分法(Bisection method) 即一分为二的方法. 设[a,b]为R的闭区间. 逐次二分法就是造出如下的区间序列([an,bn]):a0=a,b0=b,且对任一自然数n,[an+1,bn+1]或者等于[an,cn],或者等于[cn,bn],其中cn表示[an,bn]的中点(这是百度百科上对二分法的定义)
如果这样还是太深奥,那我就来举个简单的例子
假如你是一个编程大佬图书管理员,现在还有2分多钟就到下班时间了。你本来准备收拾收拾东西就回家的,却突然看到门口一辆大卡车装着两千本书,“哗”地一下全倒地上,让你来收拾。(是不是已经感受到绝望了)
面对两千本书,你需要按照书的序号来排列。假设你放一本书需要2秒,一本一本放的话也就是说需要2*2000=4000秒,4000秒≈1小时,这也就意味着你要加班1小时才能放好2000本书。这样肯定是不行的,工作效率也太低了吧。那这时我们就需要一种快速的排序方法:二分!
你可以随便选一本书拿在右手上,再不断地从书堆里拿书,看到比右手上这本书大的,管他三七二十一,全扔右边;看到比右手上的书小的,全扔左边。扔完以后,你会发现2000本书被你分成了两堆。然后你再从每一堆里面随便挑一本书作为标准,继续往左往右扔书……扔着扔着,你就会发现,你已经排好序了!(神不神奇!)
这样做效率非常高(我就懒得算了,知道效率高就行了,扔书肯定比放书快嘛)
这基本上就是二分的思想了,其实也不难,但是网上的那些解释都太深奥了,像我这种小白都看不懂……
那么,二分究竟如何用程序实现呢?
大概思路是这样的:
L(left) 是左端点,R(right)是右端点,MID(middle)是中间端点。初始值左端点放在数据开始的位置,右端点放在末尾的位置,中间端点为 ( L+R ) / 2。 然后用逼近思想去逐步逼近答案就行了。
模板大概就是这样的:
这个是向左边找答案的模板
向左边找答案: while(left这个就是向右边找答案的模板
向右边找答案: while(left模板都看过了,还不整道题巩固巩固嘛
描述给出一串数以及一个数字 C,要求计算出所有 A - B = C 的数对的个数(不同位置的数字一样的数对算不同的数对)。
输入输入共两行。
第一行,两个整数 N, C。
第二行,N 个整数,作为要求处理的那串数。
输出一行,表示该串数中包含的满足 A - B = C的数对的个数。
代码如下(这次带注释了,应该会更清楚一些):
#includeusing namespace std; long long n,c,a[2000001],cnt,st; int main(){ cin>>n>>c; for(int i=1;i<=n;i++) cin>>a[i]; sort(a+1,a+1+n);//先排序 for(int i=1;i =c) r=mid;//判断:在目标值的右边,满足,往左来 else l=mid+1; } if(a[l]-a[i]==c) st=l;//能找到C就继续 else continue; l=st-1,r=n;//查找A最后出现的位置 while(l 好啦,二分说完了,下期我来说说binary_search函数的运用吧
再见~



