首页 > 其他分享 >二分查找(折半查找)(内含CodeForces - 1760F )

二分查找(折半查找)(内含CodeForces - 1760F )

时间:2024-11-19 16:13:52浏览次数:3  
标签:折半 二分 int ll CodeForces mid 查找 数组

在数组中想要找到一个元素,我们最先想到的就是遍历数组,用if语句判断它们是否相等,但时间复杂度太高,我们也不想遍历数组中的每个元素,感觉太麻烦了。这时就可以用二分查找的方法:先将数组排序,然后不断折中数组,只需比较中值与目标值的大小,更新中值的大小就行了,这样可以大大减少时间复杂度。

下面是非递归的二分查找方式:(用了个while循环来不断更新mid的值以及端点值)

int Find(int *a,int n,int v){
	int low=0,high=n-1,mid;
	while(low<=high){
		mid=(low+high)/2;
		if(a[mid]==v) return mid;
		else if(a[mid]<v) low=mid+1;//往右边大的找 
		else high=mid-1;//往左边小的找 
	}
	return -1;
}

下面是递归的二分查找方式:

int Find(int *a,int low,int high,int v){
	if(low>=high) return -1;
	int mid=(low+high)/2;
	if(a[mid]==v) return mid;
	else if(a[mid]<v) return Find(a,mid+1,high,v);
	else return Find(a,low,mid-1,v);
}

注意!这些数组都是有序数组(从小到大),如果数组是无序的,使用二分查找之前时一定要先进行排序。

当然,#include<algorithm>头文件中包含的lower_bound(begin,end,v)函数也可以用于查找(作用:返回大于等于v元素的最小元素的指针)。注意!lower_bound返回的是一个指针,所以还要减去数组首地址。类似的,还有upper_bound函数(作用:返回数组中大于v元素的最小元素的指针)

	int x;
	cin>>x;
	int p=lower_bound(a,a+length,x)-a;
	if(a[p]==x) cout<"found"<<endl;
	else cout<<"no found"<<endl;

那么是只有查找具体元素这种时候才会用到二分查找吗?当然不是!

当题目让你去找一个答案,这个答案满足条件A,让你去求answer的最大最小值,如果没有具体公式,我们求解起来还是非常困难的,如果answer还具有单调性,我们不妨直接用二分查找,测试它是否满足条件,如果满足条件,继续二分,看它是不是最值。

#include<iostream>
#include<algorithm>
#include<cstring> 
using namespace std;
typedef long long ll;
ll s[200005];
ll e[200005];
bool comp(ll a,ll b){
	return a>b;
}//希望得到最小的k,所以需要先做金币多的任务
int main(){
	int t;
	cin>>t;
	while(t--){
		ll n,c,d;
		cin>>n>>c>>d;
		memset(s,0,sizeof(s));
		memset(e,0,sizeof(e));//必须初始化,因为我们用到了空数组,而我们不能让它为空 
		for(int i=1;i<=n;i++){
			cin>>s[i];
		}
		sort(s+1,s+1+n,comp);//排序 
		for(int i=1;i<=max(n,d);i++){
			e[i]=e[i-1]+s[i];
		}
		if(e[min(n,d)]>=c){
			cout<<"Infinity"<<endl;
		}
		else if(s[1]*d<c) cout<<"Impossible"<<endl;//k等于0都没用 
		else{
			ll r=1,l=d-1,k;//k不可能等于d,所以直接用d-1 
			while(r<=l){
				ll mid=(r+l)/2;
				ll x=e[mid]*(d/mid)+e[d%mid];//循环使用s数组 
				if(x>=c){
					k=mid-1;//因为现在索引从1开始 
					r=mid+1;
				}
				else{
					l=mid-1;
				}
			}
			cout<<k<<endl;
		}
		
	}
	return 0; 
} 

 

标签:折半,二分,int,ll,CodeForces,mid,查找,数组
From: https://blog.csdn.net/2401_87910500/article/details/143809686

相关文章

  • Linux系统怎么通过端口号查找完整进程
    需求已知某进程启动了一个端口号,怎么才能知道改进程的完整启动命令查找过程例如本机已经启动了8006端口通过端口PID可以查看到改端口启动的进程PID是6120#lsof-i:8006COMMANDPIDUSERFDTYPEDEVICESIZE/OFFNODENAMEpt_main_t6120xiaoxing93u......
  • brew 安装的Mysql,查找my.cnf文件位置
    通过Homebrew安装的MySQL,默认情况下不会创建my.cnf文件,但你可以按照以下方式找到配置文件的路径或者创建一个自定义的my.cnf文件:查找默认配置文件位置1.查看MySQL默认使用的配置文件路径:你可以通过运行以下命令来查看MySQL会读取的配置文件路径顺序:mysql--help|......
  • Codeforces Round 988 (Div. 3) E题解析
    E题题目链接CodeforcesRound988(Div.3)题目描述题目的思路根据题目的意思,我们可以推断出算法时间复杂度应该在O(N)对于这道题而言,我们可以分析下思路首先我们先从1~n的范围里面询问答案如果出现0就跳过,因为无序操作如果出现非0答案temp就记录下1~i的01序列的个数如果......
  • Codeforces Round 988 (Div. 3) A~D
    CodeforcesRound988(Div.3)A.Twice这个题就是简单的贪心题,在相同大小的元素里面,我们只能选择两个来对评分更新,所以最多能更新(相同元素的个数)/2次,记录相同元素的个数就行了//Problem:A.Twice//Contest:Codeforces-CodeforcesRound988(Div.3)//URL:https......
  • 题解:CF contest 2037 : [Codeforces Round 988 (Div. 3)] (A-E)
    ATwice题面Kinich醒来迎接新的一天的开始。他打开手机,查看邮箱,发现了一份神秘的礼物。他决定打开礼物的盒子。Kinich用\(n\)整数打开数组\(a\)。最初,Kinich的分数是\(0\)。他将执行任意次数的以下操作:—选择两个索引\(i\)和\(j\)\((1\leqi\lt;j\leqn)\),确......
  • Codeforces Round 988 (Div. 3)
    CodeforcesRound988(Div.3)总结A没啥好说的,用桶存出现次数。#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue>#include<map>usingnames......
  • 文件查找
    作用:根据不同的文件类型查找出想要的文件语法结构: find在哪里找找什么类型的#格式1 find/dataf find/data按照名称查找#格式2【1】、常用文件类型文件类型:f#表示普通文件d#表示目录l#表示链接文件c#表示字......
  • Solution - Codeforces 1957E Carousel of Combinations
    首先这个\(C(i,j)\bmodj\)的形式就非常怪,于是首先肯定要先研究一下这个值。先考虑如何求\(C(i,j)\)。可以考虑先选出要用的\(j\)个数,再乘上其排列成环的方案数,那么有\(C(i,j)=\binom{i}{j}\times(j-1)!\)。那么就是来考虑\(\binom{i}{j}\times(j-1)!\bmod......
  • Codeforces Round 987 (Div. 2) - 比赛总结
    Preface我是若只。A.PenchickandModernMonument先吃三发罚时。最优策略应当是把所有数都调成众数,然而我一开始就忙着往后面做,胡乱猜了个结论就WA了,又猜了一个又WA了,再猜了一个再WA了。点击查看代码constintN=105;intn,a[N];intmain(){ intT;read(T);......
  • Codeforces Round 986 (Div. 2)
    CodeforcesRound986(Div.2)总结A按题意模拟即可,因为\(n,a,b\)很小,可以多循环几遍来判断。只循环十遍的吃罚时qwq。#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#include<vector>#include<queue&......