整数二分与浮点数二分

整数二分

本质:边界,如某种性质在某左/右满足/不满足,寻找其边界点

注意:有单调性一定可以二分,可以二分不一定需要有单调性

类型1

[l,r]--->[l,mid-1]+[mid,r]  左区间的右边界点
找中间值:mid=(l+r+1)/2
判断中间值是否满足性质,满足则左(边界在mid-r之间),否则右(边界在l-mid-1之间)
更新区间:l=mid或r=mid-1

类型2

找中间值:mid=(l+r)/2
判断中间值是否满足性质,满足则右(边界在l-mid之间),否则左(边界在mid+1-r之间)
更新区间:r=mid或l=mid+1

代码示例

题目要求:输入数组长度和问询个数,输入升序数组,输出所问询数字的起始下标和结束下标,否则输出-1

const int N = 100010;
int n, m;
int q[N];
int main()
{
	//读入长度和问询个数
	scanf("%d%d", &n, &m);
	//读入数据
	for (int i = 0; i < n; i++)
	{
		scanf("%d", &q[i]);
	}
	while (m--)
	{
		//输入查询对象
		int x;
		scanf("%d", &x);
		//定义边界
		int l = 0, r = n - 1;
		//找左边界(第一个等于x的数)
		while (l < r)
		{
			//定义中间点
			int mid = (l + r) / 2;
			//更新边界
			if (q[mid] >= x) r = mid;
			else l = mid + 1;
		}
		//如果不存在x,经过上述循环,l和r是相等的,左边界值是一定不等于x的
		if (q[l] != x) printf("-1\n");
		else
		{
			printf("%d ", l);
			//找右边界(最后一个等于x的数)
			//定义边界
			int l = 0, r = n - 1;
			while (l < r)
			{
				//定义中间点
				int mid = (l + r + 1) / 2;
				//更新边界
				if (q[mid] <= x) l = mid;
				else r = mid - 1;
			}
			printf("%d ", l);
		}
	}
	return 0;
}

浮点数二分

示例:开平方

int main()
{
	//输入数据
	double x;
	cin >> x;
	if(x>=1)
	{
		//定义区间
		double l = 1, r = x;
		while (r - l > 1e-8)//至少要比要求的有效位数多2,要求4位就-6,6位就-8
			//也可以不用精度控制,可以直接循环100次
		{
			//不需要考虑边界问题
			double mid = (l + r) / 2;
			if (mid * mid >= x) r = mid;
			else l = mid;
		}
		printf("%lf\n", l);
	}
	else
	{
		double l = x, r = 1;
		while (r - l > 1e-8)
		{
			double mid = (l + r) / 2;
			if (mid * mid >= x) r = mid;
			else l = mid;
		}
		printf("%lf\n", l);
	}
	return 0;

值得注意的是,对于浮点数二分,我们是不需要考虑l和r的边界问题的,即不可以直接将mid赋值给l或r

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值