0
点赞
收藏
分享

微信扫一扫

算法笔记(2) 二分模板

田妞的读书笔记 2022-04-04 阅读 68
算法

二分

分为两个部分
1.整数二分
2.浮点数二分

整数二分

有单调性一定可以二分
可以二分的题目不一定必须要有单调性
所以二分的本质并不是单调性
给定一个性质在区间右半边满足在区间左半边不满足
如果可以找到这样一个性质使得整个区间一分为二,一半满足一半不满足
二分可以寻找这两个区间的边界
二分不同的区域使用不同的模板
整数二分:
	l |---------------___________________| r
既可以找到'---'区域的右边界,也可以找到'___'区域的左边界

第一个模板(寻找’—'区域的右边界)

如何二分出来'---'边界点
(1) 中间值
	mid=(l+r+1)/2;//如果不加1的话,当l=r-1的时候就会变成死循环
	if(check(mid))	//是否满足'---'性质
		true: mid一定在'---'区间里,答案在[mid,r],mid可能是答案 
		l=mid
		false:	答案在[l,mid-1], r=mid-1

第二个模板(寻找’___'区域的左边界)

	mid=(l+r)/2;
	if(check(mid))
		true: [l,mid] r=mid
		false; [mid+1,r]	l=mid+1

采用哪个模板:

先写一个Mid
根据Check思考如何选择模板
先不写加1 想想二分的哪个边界,然后写判断,如果是true在哪个边界,
两种二分的方式,一种方式补上加一,一种不用补上加一,二分的哪个边界,性质是什么

二分算法一定可以把边界二分出来,如果题目中有找不到结果的情况,那么需要
按相应的情况去做一个判断。

浮点数二分:

边界问题
答案在[l,r]
通过二分找到边界出来
浮点数不存在整除问题
每一次通过中间点查看是否找到答案,当区间长度足够小的话可以认为足够小了
例子:
	开平方
int main() {
	int x;
	scanf("%d",&x);
	double l=0,r=x;
	while(r-l>1e-8)	 //bi比要求的有效位数多2
	{
		double mid=(l+r)/2;
		if(mid*mid>=x)
			r=mid;
		else
			l=mid;
	}
	cout<<l<<endl;
	return 0;
}

第二种写法

for(int i=0;i<100;i++)//不管如何迭代一百次
{
		double mid=(l+r)/2;
		if(mid*mid>=x)
			r=mid;
		else
			l=mid;
}
举报

相关推荐

0 条评论