首页 > 其他分享 >复习:二分

复习:二分

时间:2024-01-05 22:56:49浏览次数:19  
标签:二分 return 复习 int mid 区域 答案

二分是我之前也没怎么好好学的一部分,这次顺带着理解了一些之前不太理解的东西

首先是二分的意思,实际上是一种对区间进行每次处理时都只取区间的一半,然后是一半的一半,一半的一半的一半....

因此对于长度为n的序列而言,一个单独二分的复杂度是logn

那么在什么情况下我们可以想到用二分呢?

我们从这个方法本身来看,既然每次都要取一半,那我们就要清楚哪一半究竟才是正确的

我们会取一个mid值,一般将[l,r]区间划分为[l,mid]和[mid+1,r]或者[l,mid-1]和[mid,r](对于整数而言)

我们每次都要对mid处的值进行检查,以此来判断要求的答案是在左边区域还是右边区域。

也就是说,如果无法区分左边区域和右边区域哪个正确,也就无法二分

所以左边的区域必须有一种性质,右边区域有另外一种性质。这种性质一般就是是否满足某个条件。

并且由于二分到最后范围会缩小到一个数,因此序列里的所有数都可能会成为mid。每次都要对mid处值进行判定。所以对于每个序列上的数而言,都可以从左边的区域和右边的区域中选择正确的一个

像这样不论对哪个位置而言,都有一边满足条件,另一边不满足,可以把它叫做答案的单调性

当对象是单调数列时,我们很容易能想到二分。但当答案具有单调性时我们却不太容易注意到

洛谷P2249

很经典的单调序列查找,需要找到改数字第一次在序列中出现的位置

当mid处的值小于答案时,说明答案在右半部分,大于时,答案在左半部分

等于时,可能是该位置本身,也可能是左边的区域。因此划分区域时最好直接选择[l,mid]将mid自身划进去

#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[1000005];
void ser(int l,int r,int ans)
{
	if(l>r) return;
	if(l==r)
	{
		if(ans!=a[r])
		{
			printf("-1 ");
			return;
		}
		printf("%d ",l);
		return;
	}
	int mid=(l+r)>>1;
	if(a[mid]<ans) ser(mid+1,r,ans);
	else ser(l,mid,ans);
}
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	for(int i=1;i<=m;i++)
	{
		int q;
		scanf("%d",&q);
		ser(1,n,q);
	}
	return 0;
}

洛谷P1824

这个就是答案的单调性。

要将牛插入进牛棚里,求最大的最近距离,范围是1e9

设这个最大的最近距离为F,当最近距离小于F时满足可以把牛都填进去这一条件

当最近距离大于F时,必然无法填完,因为F是最大的满足该条件的

因此在牛棚区域内进行二分,对于每个mid看看是否满足条件来判断答案在左还是在右。

判断方法为从1到n循环,从第一个开始填,很显然当一个位置减去上一个填的位置得到的结果大于设定的最近距离时便可将其填入。并且当i为1时是必填入的。循环完后查看是否将牛填完

复杂度最大为nlog1e9

#include<bits/stdc++.h>
using namespace std;
int n,c;
int a[100005]; 
bool cmp(int mid)//判断该最近距离是否合法 
{
	int last=1,sum=1;//第一个是肯定要加进去的 
	for(int i=2;i<=n;i++)
	{
		if(a[i]-a[last]>=mid) last=i,sum++;
	}
	if(sum>=c) return true;
	else return false;//放不了c头 
}
void ser(int l,int r)
{
	if(l>r) return;
	if(l==r) 
	{
		printf("%d",l);
		return;
	}
	int mid=(l+r+1)/2;
//cout<<l<<' '<<r<<endl;
	if(!cmp(mid)) ser(l,mid-1);//最近距离大于F 
	else ser(mid,r);
	return;
}
int main()
{
//求最近距离的最大值,设为F,当最近距离大于F时
//没有方案安置牛棚,当最近距离小于等于F时则一定存在至少
//一种方案 
//在(1,Xn)范围内进行二分,对每个mid作为最近距离进行判定
//
	 
	scanf("%d%d",&n,&c);
	for(int i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	sort(a+1,a+n+1);
	ser(1,a[n]);
	return 0;
}

洛谷P1024

这题数据很弱,暴力枚举也能过,最后保留两位,即使枚举1e-4的精度也只有2*1e6

但目的是为了练二分....

这道题给了一个判定条件,并且每个答案相差大于1,因此可以对-100到100的200个区间分别进行二分

当区间边界已经接近答案时用判定条件将无法生效,因为代入原式直接就是0,因此直接输出后return即可

区间只用输出一个端点即可,两个端点会重复

#include<bits/stdc++.h>
using namespace std;
double a,b,c,d;
double minn=1e-4;
void search(double l,double r)
{
	if(l>r) return;
	if(r-l<=minn)
	{
		printf("%.2lf ",l);
		return;
	}
	//printf("%.2llf %.2llf\n",l,r);
	double mid=(l+r)/2;
	double fx1=a*l*l*l+b*l*l+c*l+d,fx2=a*r*r*r+b*r*r+c*r+d;
	double fm=a*mid*mid*mid+b*mid*mid+c*mid+d;
	if(fx1==0) {printf("%.2lf ",l);return;}
	if(fx2*fm<0) search(mid+minn,r);
	if(fx1*fm<0) search(l,mid);
}
int main()
{
	//范围是-100到100 
	cin>>a>>b>>c>>d;
	for(int i=-100;i<=99;i++)
	{
		search(double(i),double(i+1));
	}
	return 0;
}

标签:二分,return,复习,int,mid,区域,答案
From: https://www.cnblogs.com/miku-dayo/p/17948264

相关文章

  • [NLP复习笔记] 朴素贝叶斯分类器
    1.贝叶斯决策论假设有\(N\)中类别标记\(\gamma=\{c_1,c_2,\dots,c_N\}\),\(\lambda_{ij}\)是将一个真实标记为\(c_{j}\)分类为\(c_i\)所产生的损失。基于后验概率\(P(c|\mathbf{x})\)可以得到样本\(\mathbf{x}\)分类为\(c_i\)的期望损失(\(\text{expectedlo......
  • (五十二)C#编程基础复习——C#点阵列
    在C#中,点阵列类用来管理一个紧凑型的位值数组,数组中的值均为布尔类型,其中true(1)表示此位为开启,false(0)表示此位为关闭。当你需要存储位(英文名“bit”数据存储的最小单位,也可称为比特),但事先又不知道具体位数时,就可以使用点阵列。当需要访问点阵列中的元素时,可以使用整型索引从点阵......
  • (五十一)C#编程基础复习——C#队列
    在C#中,队列类与堆栈类类似,它代表了一个先进先出的对象结合,当你需要对项目进行先进先出访问时,则可以使用队列。向队列中添加元素称为入队,从堆栈中移除元素称为出队。一、队列类中的属性下表中列出了队列类中的一些常用属性二、队列类中的方法下表列出了队列类的一些常用方法......
  • [NLP复习笔记] N-gram 及基本平滑方法
    1.N-gram模型1.1N-gram模型介绍\(\text{N-gram}\)是一种基于统计语言模型的算法,用于预测文本中的单词,其中\(\text{N}\)一般指的是序列中的单词数量。其基本思想是将文本内容进行大小为\(\text{N}\)的滑动窗口操作来计算概率。例如:当\(\text{N}=1\)时,模型被称为"u......
  • (五十)C#编程基础复习——C#堆栈
    在C#中,堆栈类表示一个后进先出的对象集合,当你需要对项目进行后进先出的访问时,则可以使用堆栈。向堆栈中添加元素称为推入元素,从堆栈中移除元素称为弹出元素。一、堆栈类中的属性下表列出了堆栈类中的一些常用的属性二、堆栈类中的方法下面列出了堆栈类中一些常用的方法示例......
  • 软件工程 之 (XMUT)Java期末复习题及答案-选择题
    软件工程实用案例教程https://www.cnblogs.com/IvanKK/p/17712702.htmlJava期末复习题及答案https://www.cnblogs.com/IvanKK/p/17712704.html计算机网络复习题库https://www.cnblogs.com/IvanKK/p/17712719.html(XMUT)Java期末复习题及答案-选择题分数1作者张峰单位......
  • vue 2实战系列 —— 复习Vue
    复习Vue近期需要接手vue2的项目,许久未写,语法有些陌生。本篇将较全面复习vue2。Tip:项目是基于ant-design-vue-proant-design-vue-pro由于cms是基于这个项目开发的,所以笔者就将其下载下来。下载后运行//按照依赖yarninstall//本地启动yarnrunserve根据提......
  • 算法复习
    目录渐近记号O记号Ω记号Θ记号分治策略分治算法的效率分析迭代法求运行时间递归树法求运行时间主定理法求运行时间渐近记号O记号渐近上界记号O(大O)渐近地给出了一个函数在常量因子内的上界:O(g(n))={f(n):存在正常量c和n0,使得对所有n≥n0,有0≤f(n)≤cg(n)}f(n......
  • 生物统计复习
    1.绪论1.1统计学研究数据的收集、整理、分析和解释的科学,是处理数据中变异性的科学和艺术。统计分析可分为统计描述和统计推断两部分统计描述:用统计图表、统计指标或几个特征数描述资料的数据特征和分布规律统计推断:用样本信息来推断总体特征目的:求得可靠的结......
  • 二分查找算法---java----黑马程序员算法
    1.二分查找算法给定的条件:给定的有序数组A查找目标值为target,其中A标记为 数组序号从0开始,其下标最大为数组长度-1.举例数组:5  14  22 30 31  41 44条件:i>j  i表示左边下标   j表示右边下标   i从5开始   j 从44开始思想:每次计算其......