首页 > 其他分享 >二分基础

二分基础

时间:2023-04-12 23:22:24浏览次数:33  
标签:二分 return int double sum 基础 mid 大于

复健\(Day2\)

今天复习二分,使用这种方法的比较明显的提示是使最大值最小,最小值最大,并且原序列有序或者说可以忽略次序

二分的基本模板

https://www.acwing.com/blog/content/2112/

题目

\(1.Acwing102\)

https://www.acwing.com/problem/content/104/

向下取整函数\(floor\),\(double\) \(floor\)\((double\) \(arg)\),向上取整函数\(ceil\),用法与\(floor\)相同

#include<iostream>
#include<cstdio>
#include<cmath>
#define EPS 1e-5
#define maxn 100010
using namespace std;

int n,F;
int s[maxn];
double sum[maxn];

int Min(int a,int b)
{
	return a>b?b:a;
}

int Max(int a,int b) 
{
	return a>b?a:b;
}

bool check(double ans)//双指针做法 
{
	for(int i=1;i<=n;i++)
	{
		sum[i]=sum[i-1]+s[i]-ans;
	}
	double minv=0;
	for(int i=0,j=F;j<=n;i++,j++)
	{
		minv=min(minv,sum[i]);
		if(sum[j]-minv>=0) return true;
	}
	return false;
}

int main()
{
	cin>>n>>F;
	double l=2000.0,r=1.0;
	for(int i=1;i<=n;i++)
	{
		cin>>s[i];
		l=Min(l,s[i]);
		r=Max(r,s[i]);
	}
	while(r-l>EPS)
	{
		double mid=(l+r)/2.0;
		if(check(mid)) l=mid;
		else r=mid;
	}
	printf("%d\n",int(r*1000));
	return 0;
}

这道题要求我们找到一段长度大于等于\(F\)的区间,这段区间里牛的平均数要使得其最大

首先我们可以考虑到采用二重循环,枚举区间长度(大于等于F)以及起点,这样的时间复杂度是略小于\(O(n\ ^2)\)(在前缀和预处理的情况下)

我们思考要如何优化,在前缀和上考虑进行处理。平均数有一个很明显的性质,某个数减去平均数如果大于\(0\),那么它本身就是大于平均数的,若小于\(0\)就是小于平均数的。因此我们用\(sum[i]\)记录\(s[1]-avg+s[2]-avg+s[3]-avg+...+s[i]-avg\)。

然后我们用两个指针\(i\)和\(j\),我们初始化\(i=0,j=F\),然后每次循环都\(i++,j++\)这样我们就可以保证\(i\)和\(j\)之间的距离始终保持为\(F\).

\(sum[j]-sum[i]\geqslant0\)时显然这一段的数减去平均大于等于\(0\),也即满足平均值大于等与该二分的答案,这样是考虑了长度为\(F\)的区间,而对于大于\(F\)的区间,我们又用一个\(minv\)记录从\(1\)至\(i\)的过程中\(sum[i]\)的最小值,这是最优的一个最小值,当我们\(sum[j]-minv\geqslant0\)时,那么我们的平均值就满足条件了并且保证了区间长度大于等于\(F\)了

这样\(check\)函数就优化成了\(O(n)\)的复杂度了

\(Acwing113\)

https://www.acwing.com/problem/content/115/

关于交互式问题

// Forward declaration of compare API.
// bool compare(int a, int b);
// return bool means whether a is less than b.

class Solution {
public:
    vector<int> specialSort(int N) {
        vector<int> v;
        v.push_back(1);//将1装入v中,便于比较
        for(int i=2;i<=N;i++)
        {
            int l=0,r=v.size()-1;
            while(l<r)//找到第一个小于i的位置r
            {
                int mid=(l+r+1)>>1;//这里注意是l+r+1>>1
                if(compare(v[mid],i)) l=mid;//v[mid]<i
                else r=mid-1;
            }
            v.push_back(i);//把i放在v的最后一个位置
            for(int j=v.size()-2;j>r;j--)//将i放在r+1的位置,然后把原本在r+1以及以后的数都往后移一位
            {
                swap(v[j],v[j+1]);
            }
            if(compare(i,v[r])) swap(v[r],v[r+1]);//i可能是最小的元素,v[r]仍然大于i,故这个时候我们做一个特殊判断
        }
        return v;
    }
};

注意到我们这里的二分部分给的边界条件是\(l<r\),然后\(mid\)的计算式\((l+r+1)>>1\)

标签:二分,return,int,double,sum,基础,mid,大于
From: https://www.cnblogs.com/iwillenter-top1/p/17311855.html

相关文章

  • 计算机网络基础
    网络的基本组件? 设备介质  服务网络介质网络介质两大类:有线 wire铜质介质双绞线 twistedpairTP (8根线,4对线)  为什么双绞?抗干扰UTP 非屏蔽双绞线 unshieldedTP            (2)STP屏蔽双绞线  shieldedTPSTP的抗干扰性能优于UTP,但价格更贵,日常......
  • k8s详细教程零基础
    Kubernetes(k8s)作为云原生的核心平台,吸引了越来越多的运维、开发、测试以及其他技术员去了解学习,随着行业越来越内卷,k8s已经被广泛使用,作为一名运维人员,k8s将成为一个必须掌握的技术点·,同时,我们也可以依靠它跳槽涨薪。一、什么是k8s它前生是谷歌的Borg系统,后经过Go语言重写,在2014......
  • ssh的基础使用与端口转发
    基础使用基本连接SSH基本的连接命令是:sshusername@hostname这里牵扯到了两台主机执行命令、运行SSH客户端的主机,我们称为本地主机A【HostA】;接收连接请求、运行SSH服务器的主机,我们称为远程主机B【HostB】。通过密码或密钥等方式验证后,SSH连接建立,主机A可以使用命令......
  • 哈希表理论基础——学习笔记
    常见的三种哈希结构数组set(集合)map(映射)HashSet特点:HashSet无序(没有下标),不可重复HashSet为HashMap的key部分TreeSetTreeSet无序(没下标),不可重复,但是可以排序TreeSet为TreeMap的key部分mapMap和Collection没有继承关系Map以(k......
  • 二分图学习笔记
    定义>\(1.\)点数量\(\ge\)2>\(2.\)没有奇环二分图染色>深搜,0和1两种,相邻染不一样颜色,如果最后有冲突就不是二分图。二分图匹配>######定义>>没有\(2\)条边公用\(1\)个点>>--->>######极大匹配>>无法通过加边的方式增加匹配的数量>>--->>###......
  • js基础
    //js会把var声明的变量提升到js文件的最顶部//控制台打印语句//console.log('你好!');//警告框!通知用户出错了//alert('haha')//输入框-输入内容prompt得到的输入内容永远都是字符串//varn1=prompt("第一个数")//varn2=prompt("第二个数")//使用弹......
  • JavaScript基础知识
    JavaScript基础知识JavaScript是什么?JavaScript是一门编程语言,可以实现很多的网页交互效果。开web页面的脚本语言JavaScript的书写位置?内部JavaScript写在body结束标签上方script里面外部JavaScript通过scriptsrc=引入js文件但是script里面不要写内容,否则会被忽略JavaSc......
  • Java基础语法
    注释、标识符、关键字注释注释并不会被执行,是给我们程序员看的书写注释是一个非常好的习惯Java注释的分类:单行注释://多行注释:/****/文档注释标识符标识符的作用用来表示变量名、类名、方法名、数组名和文件名等是一个有效的字符序列......
  • c#中byte数组0x_(C#基础) byte[] 之初始化, 赋值,转换。
    c#中byte数组0x_(C#基础)byte[]之初始化,赋值,转换。原文链接:https://blog.csdn.net/weixin_39862716/article/details/111506430byte[]之初始化赋值用forloop赋值当然是最基本的方法,不过在C#里面还有其他的便捷方法。1.创建一个长度为10的byte数组,并且其中每个byte的......
  • 第二章 MATLAB语言基础
    一、基本概念1、MATALAB主要数据类型 2、整数类型MATLAB中提供了8种内置的整数类型,如下:由于MATLAB中数值的默认存储类型是双精度浮点类型,因此必须通过表2-1中列出的转换函数将双精度浮点数值转换成指定的整数类型。在转换中,MATLAB默认将待转换数值转换为最近......