首页 > 其他分享 >二分与双指针

二分与双指针

时间:2024-03-15 21:13:18浏览次数:24  
标签:二分 int ll mid long 模板 指针

目录

一. 二分

   会二分首先得会二分模板吧

1. 二分模板

typedef long long LL;   //long long 简写
LL l = 左边界,LL r = 右边界   //左右边界需自己读题分辨
while(l + 1 < r)
{
    LL mid = (l + r )>>1;                //'>>1'表示除2,与'/2'一样,只是比单纯除以2要快点
    if(check(mid))(r or l) = mid;        //左边满足条件,l = mid;
    else (l or r) = mid;                 //右边满足条件,r = mid;
}

2. 什么情况下能用到二分?(时间复杂度是O(logn))

  一般用for循环遍历WA的题,可尝试用二分,说不定AC了呢!!

1.在一个有序数组中,找某个数是否存在

2.在一个有序数组中,找>=某个数最左侧的位置

3.局部最小值的问题

3. 二分使用方法

  1. 套模板
  2. 2.确定返回值(答案)是l or r;
  3. 是 l 就是 l = mid,是 r 就是 r = mid;
  4. 通过答案的范围来确定边界
  5. 写check
  6. AC

4. 例题(注重理解!!!)

  1. P1024 [NOIP2001 提高组] 一元三次方程求解
    题目链接:https://www.luogu.com.cn/problem/P1024
    题解:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
double a,b,c,d;
int ans=0;
double f(double x)
{
	return a*x*x*x+b*x*x+c*x+d;// 计算一元三次方程的值
}
int main(){
	scanf("%lf %lf %lf %lf",&a,&b,&c,&d);
	for(int i=-100;i<100;i++){
		double l=i,r=i+1;//  找到左边界与右边界
		if(!f(l)){//   如果有满足f(x)=0的情况就输出
			printf("%.2lf ",l);
			ans++;
		}
		if(f(l)*f(r)<0){//  判断零点条件
			while(l+0.001<r){
				double mid=(l+r)/2;//  更新条件
				if(f(mid)*f(r)<=0){
					l=mid;// 左边界小了
				}
				else{
					r=mid;//  右边界大了
				}
			}
			printf("%.2lf ",r);
			ans++;
		}
		if(ans==3)break;// 只需从小到大输出满足条件的三个
	}
	return 0;
}
  1. 木材加工
    题目链接:https://www.luogu.com.cn/problem/P2440
    题解:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=2e6+5;//注意范围
int n,k,x[maxn];
int check(ll mid)
{
	int cnt=0;//用来记录所切木头根数
	for(int i=0;i<n;i++){
		cnt+=x[i]/mid;//计算能切多少根
	}
	if(cnt>=k)return 1;//如果能满足k段木头返回真
	else return 0;//否则假
}
int main()
{
	cin>>n>>k;//读入n根木头和要得到的k段木头
	for(int i=0;i<n;i++){
		cin>>x[i];//读入每根木头的长度
	}
	ll l = 0,r = 1e8+1;//模板套用,最小边界为0(一根也切不出来),最大边界为题目所给定的
	while(l + 1 < r){
		ll mid = (l + r) >> 1;
		if(check(mid)) l = mid;//如果mid为真,说明所切的木头还可以更大
		else r = mid;//否则就减小所切长度
	}
	cout<<l<<endl;//最后输出正确结果
}
  1. 【深基13.例1】查找
    题目链接:https://www.luogu.com.cn/problem/P2249
    题解:

二.双指针

  相比二分,双指针我觉得比二分好理解,直接上题!

Eating Candies
题目链接:https://www.luogu.com.cn/problem/CF1669F
题解:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll maxn=2e6+5;
int a[maxn],n;
int main()
{
	int t;
	cin>>t;//测试样例数
	while(t--){
		cin>>n;
		for(int i=0;i<n;i++){
			cin>>a[i];//读入每组数据
		}
		ll l=0,r=n-1;//左值为数组下标第一位,右值为数组下标最后一位
		int cnt=0,Alice=0,Bob=0,candy=0;//Alice,Bob记录各自吃到的糖果,candy记录一共吃的糖果数量
		while(l<=r){
			if(Alice<=Bob){
				Alice+=a[l];//从Alice开始吃
				l++;//吃一颗,下标往右移
				candy++;
			}
			else{
				Bob+=a[r];//糖果重量Alice>Bob时,Bob开始吃
				r--;//吃一颗,下标左移
				candy++;
			}
			if(Alice==Bob){
				cnt=max(cnt,candy);//当糖果重量相等时,就比较一次糖果数谁多,取最多糖果数
			}
		}
		cout<<cnt<<endl;//最终输出最多糖果数
	}
}

完结!!!

标签:二分,int,ll,mid,long,模板,指针
From: https://www.cnblogs.com/yishujia/p/17895490.html

相关文章

  • 小y的序列(ST表&二分)---牛客练习赛96-C
    牛客练习赛96-小y的序列解析ST表预处理区间极值差可以发现,对于一个区间[l,r]......
  • wqs二分
    https://zhuanlan.zhihu.com/p/340514421https://blog.csdn.net/Emm_Titan/article/details/124035796https://www.cnblogs.com/TianMeng-hyl/p/14972355.htmlhttps://www.cnblogs.com/Liang-sheng/p/15182786.html......
  • 整体二分较详讲解
    看了前面所说的求第KKK大/小问题,在这里就不多赘述了.先浅浅的谈一谈二分答案(如果会二分答案请直接调到整体二分部分)二分答案二分答案就是在答案满足单调性的时候优化O(N)O(N)O(N)的枚举答案暴力变为指数级的O(log⁡n)O(\log_n)O(logn​)(有可能不......
  • 【算法】二分查找——在排序数组中查找元素的第一个和最后一个位置
    leetcode链接题目描述给你一个按照非递减顺序排列的整数数组nums,和一个目标值target。请你找出给定目标值在数组中的开始位置和结束位置。如果数组中不存在目标值target,返回[-1,-1]。你必须设计并实现时间复杂度为O(logn)的算法解决此问题。示例1:输入:nums=[5,......
  • 第八届蓝桥杯省赛 分巧克力(二分)
    题目描述:  思路:给出N个长方形的长和宽,可以分别看长能被分成多少块,宽能被分为多少块,也就是(h/mid)*(w/mid),使其大于等于K所以我们可以通过二分去找,最大的边长是多少AC代码: #include<iostream>usingnamespacestd;typedeflonglongLL;constintN=1......
  • (C++)二分
    二分​ 二分,他可以应用的范围特别广,即使是你想不到的地方他也可以二分。​ 例如:Acwing790数的三次方根这题可以直接二分题目所要求的答案,通过不断逼近三次方后的结果来二分;Acwing5407.管道,这题里可以直接二分时间,然后合并区间查看是否满足;Acwing730.机器人跳跃问题可以......
  • 【二分法】分巧克力问题/python
    1.看出是用二分法:最大值最小化,最小值最大化,满足条件的最值,用二分法做。2.确定low,high,确定check的条件3.注意: 是当low<high的时候进行循环,当相等或大于的时候输出,while的条件不能写错。 本题是在区间里面找满足条件的最大值,所以,在算mid的时候面对取整的问题让它向大......
  • c语言:深入了解指针(2)
    1.const修饰变量变量是可以修改的,如果将变量的地址传给一个指针变量,可以通过指针变量来改变这个变量的值,如果我们不想这个变量的值不能被随意更改,我们就可以使用const来修饰这个变量。intmain(){ intn=10;//n是变量 n=5; printf("%d\n",n); return0;}我们可......
  • cpp:"函数指针"的方法
    目录仿函数类std::function类Lambda类lambda函数函数对象有这几类:仿函数类即重载operator()classFuncObjType{public:voidoperator()(){cout<<"HelloC++!"<<endl;}};std::function类即上文中func_typestd::function<float(float,float)>......
  • 滴水逆向笔记系列-c语言总结6-20.多级指针 数组指针 函数指针-21.位运算-22.内存分配
    第二十课c语言13多级指针数组指针函数指针1.多级指针反汇编一二级指针可以看到p1==*(p1+0)==p1[0]本来一直没想懂为什么是movsxecx,byteptr[eax],是byte,才发现p1是char类型,所以才得用movsx拓展(p1+2)==p1[2],指针可以用和[]取值,他们是一样的(((p3+1)+2)+3)==p3[......