二分与三分(备赛中)

news2024/9/20 17:00:19

A.愤怒的牛儿

思路:找出最长距离,与最小距离,用二分法判断,如果当前距离满足放牛要求,就把距离区间l=mid+1;如果距离不合适就说明当前距离太大了,把区间变小r=mid-1;最后直到l<r不满足时退出,输出ans;ans=mid,在遍历的时候保存。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e9+10;
int num[100010];
int n,m;
int judge(int dis)
{
    int dum=1;
    int xi=num[1];
    for(int i=2;i<=n;i++)
    {
        if(num[i]-xi>=dis)
        {
            dum++;
            xi=num[i];
        }
        if(dum==m)break;
    }
	return dum==m;

}
int main()
{
   ios::sync_with_stdio(0);
   cin.tie(0);cout.tie(0);
   cin>>n>>m;
   for(int i=1;i<=n;i++)cin>>num[i];
   sort(num+1,num+1+n);
   int l=num[1];
   int r=num[n]-num[1]+1;
   int k;
   while(l<r)
   {
       int mid=(l+r)>>1;
       if(judge(mid)){k=mid;l=mid+1;}
       else r=mid;
   }
   cout<<k;
}

B.Best Cow Fences

思路:看到了平均值就知道应该要用前缀和了,我们要输出平均数最大的,当然就要考虑用二分了。我们依旧用二分法,每一次如果该平均值满足条件,我们就把区间l=mid;(这里为什么不l=mid+1;因为这样会跳过答案)。如何判断呢就是我们用前缀和,前缀和在开始的时候要把传过来的平均值直接减去,看看是否小于0即可。取最大平均值过程中是这样的,把前面最小的保存下来。然后用后面的减去那个最小值看看是否大于0即可。最好输出即可l或r。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int n,m;
double num1[maxn];
double num2[maxn];
bool judge(double ave)
{
    for(int i=1;i<=n;i++)num2[i]=num2[i-1]+num1[i]-ave;//每次都减去平均值
    double mins=maxn;//筛出最小前缀值
    for(int i=m;i<=n;i++)//从最短距离开始
    {
        mins=min(num2[i-m],mins);
        if(num2[i]-mins>0)return true;
    }
    return false;
}
int main()
{
    cin>>n>>m;
    double l=0,r=0;
    for(int i=1;i<=n;i++)
    {
        cin>>num1[i];
        r=max(num1[i],r);
    }
    while(r-l>1e-6)
    {
        double mid=(l+r)/2;
        if(judge(mid))l=mid;
        else r=mid;
    }
    printf("%d\n",(int)(1000*r));
}

C.曲线

 思路:单峰函数用三分法。具体方法如下。

#include<bits/stdc++.h>
using namespace std;
int num;
int num1;
double a[20005],b[20005],c[20005];
double judge(double x)//返回值
{
    double mas=INT_MIN;
    for(int i=1;i<=num1;i++)
    {
        mas=max(mas,a[i]*x*x+b[i]*x+c[i]);//选出最大的那个值
    }
    return mas;
}
void solves()
{
    cin>>num1;
    for(int i=1;i<=num1;i++)
    {
        cin>>a[i]>>b[i]>>c[i];
    }
    double left=0,right=1000;
    while(right>left+1e-4)//精度
    {
        double midleft=left+(right-left)/3;//三分左区间
        double midright=right-(right-left)/3;//三分右区间
        if(judge(midleft)>=judge(midright))//如果左高的话说明左离得远
        {
            left=midleft;//移动左区间
        }
        else right=midright;//否则移动右区间
    }
    printf("%.4f\n",judge(left));

}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    cin>>num;
    while(num--)
    {
        solves();
    }
}

D.数列分段

 思路:依旧是二分思路,取全和做R,取1做L,移动区间即可。对于满足条件就把区间r=mid,不满足条件就l=mid+1;最后输出r。判断函数写法具体是,看看是否能在段数不大于m的情况,满足条件。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int n,m;
ll num[maxn];
int check(int x)
{
    ll sum=0;
    int cnt=1;
    for(int i=1;i<=n;i++)
    {
        if(num[i]>x)return 0;
        sum+=num[i];
        if(sum>x)
        {
            sum=num[i];
            cnt++;
        }
    }
    return m>=cnt;
}
int main()
{
    cin>>n>>m;
    int l=1,r=0;
    for(int i=1;i<=n;i++)
    {
        cin>>num[i];
        r+=num[i];
    }
    while(l<r)
    {
        int mid=l+r>>1;
        if(check(mid))r=mid;
        else l=mid+1;
    }
    cout<<r<<endl;
}

E.扩散

 思路:依旧是二分,但需要并查集的协助,我们设置最大时间R=1e9+10,最小时间L=0.我们开始二分算法,如果当前时间满足条件,就把时间区间R=mid;否则L=mid+1.最后输出R。判断函数具体思路是我们设置二重循环,每一次访问两个点看看能不能在当前时间内是否能扩散相交。具体条件是x,y坐标差值与两倍时间的大小关系。如果小于或等于则可以扩散到,反之则不可以。如果扩散到的话就,放到并查集中,如果没有就不用放。之后看看每个点是否只有一个祖先即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int x[maxn],y[maxn];
int father[maxn];
int n;
int find(int x)
{
    if(father[x]==x)return x;
    else return find(father[x]);
}
bool check(int mid)
{
    int sum=0;
    for(int i=1;i<=n;i++)father[i]=i;
    for(int i=1;i<=n;i++)
    {
        for(int i1=i+1;i1<=n;i1++)
        {
            if(abs(x[i]-x[i1])+abs(y[i]-y[i1])<=2*mid)
            {
                if(find(i)!=find(i1))
                {
                    father[find(i)]=find(i1);
                }
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
        if(father[i]==i)sum++;
        if(sum==2)return false;
    }
    return true;

}
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>x[i]>>y[i];
    }
    int l=0,r=1e9+10;
    int ans;
    while(l<r)
    {
        int mid=r+l>>1;
        if(check(mid))
        {
            r=mid;
        }
        else l=mid+1;
    }
    cout<<r;
}

H.灯泡

 

 思路:根据计算所得影子长度就两种情况

(1)当影子不会射到墙上时,影子长度为

(2)当影子射到了墙上时,影子长度为

看函数我们将x定义为等到人的距离。看函数是一个单峰函数。所以用三分法去做。具体如下

​
#include<bits/stdc++.h>
using namespace std;
double H,h,D;
double check(double x)
{
    if(D-x>h*x/(H-h))//影子长度小于人到墙的距离
    {
        return h*x/(H-h);//返回第一种情况
    }
    else
    {
        return D-x+h-(H-h)*(D-x)/x;//反之影子在墙上,返回第二种情况。
    }
}
void solve()
{
    cin>>H>>h>>D;
    double l=0;
    double r=D;
    while(r-l>1e-6)
    {
        double midl=l+(r-l)/3;
        double midr=r-(r-l)/3;
        if(check(midl)>=check(midr))//单峰函数移动法
        {
            r=midr;
        }
        else l=midl;
    }
    printf("%.3f\n",check(r));
}
int main()
{
    int num;cin>>num;
    while(num--)
    {
        solve();
    }
}

​

 G.传送带

 思路:这道题有点难度,想了好久,学习了好久才会的。共有三段路程,一段在AB上,一段在CD上,还有一段在路上。很简单看一下,那个最少时间满足单谷函数。所以我们用三分,但未知量有两个所以我们用三分套三分。具体如下

#include<bits/stdc++.h>
using namespace std;
double Ax,Ay,Bx,By,Cx,Cy,Dx,Dy,p,q,r,ans;
double check(double x,double y)
{
	double P1x=Ax+(Bx-Ax)*x,P1y=Ay+(By-Ay)*x,P2x=Cx+(Dx-Cx)*y,P2y=Cy+(Dy-Cy)*y;
	return sqrt((P1x-Ax)*(P1x-Ax)+(P1y-Ay)*(P1y-Ay))/p+sqrt((Dx-P2x)*(Dx-P2x)+(Dy-P2y)*(Dy-P2y))/q+sqrt((P2x-P1x)*(P2x-P1x)+(P2y-P1y)*(P2y-P1y))/r;
}
double find2(double x,double l,double r)//在CD上三分
{
	double res=0.0;//返回的时间数
	while(r-l>=1e-6)//精度
	{
       double midl=l+(r-l)/3;
	   double midr=r-(r-l)/3;
	   double res1=check(x,midl);//按在AB中的比例,和CD中的比例返回时间
	   double res2=check(x,midr);
	   if(res1<res2)//缩短区间,保留答案。
	    {
		 r=midr;
		 res=res1;
	   }
	   else l=midl,res=res2;
	}
	return res;
}
void find1(double l,double r)
{
	while(r-l>=1e-6)
	{
	   double midl=l+(r-l)/3;//在AB上三分
	   double midr=r-(r-l)/3;
	   double res1=find2(midl,0,1);//用三分出来的比例在CD上看返回来的值分布情况
	   double res2=find2(midr,0,1);
	   if(res1<res2)
	   {
		  r=midr;
		  ans=res1;
	   }
	   else
	   {
	   	   l=midl;
           ans=res2;
	   }

	}
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>Ax>>Ay>>Bx>>By>>Cx>>Cy>>Dx>>Dy>>p>>q>>r;//输入
	find1(0,1);//这里的0,1是在AB上的比例。
	printf("%.2f",ans);
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/391801.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spark SQL优化机制

Spark SQL优化机制Spark SQLCatalyst 优化器逻辑优化物理优化TungstenUnsafe RowWSCGRDD 缺点 : RDD的算子都是高阶函数 &#xff0c;Spark Core 不知函数内的操作&#xff0c;只能闭包形式发给 Executors&#xff0c; 无法优化 DataFrame 不同点&#xff1a; 数据的表示形式…

AQS底层源码深度剖析-Lock锁

目录 AQS底层源码深度剖析-Lock锁 ReentrantLock底层原理 为什么把获取锁失败的线程加入到阻塞队列中&#xff0c;而不是采取其它方法&#xff1f; 总结&#xff1a;三大核心原理 CAS是啥&#xff1f; 代码模拟一个CAS&#xff1a; 公平锁与非公平锁 可重入锁的应用场景&…

C语言-基础了解-25-C强制类型转换

C强制类型转换 一、强制类型转换 强制类型转换是把变量从一种类型转换为另一种数据类型。例如&#xff0c;如果您想存储一个 long 类型的值到一个简单的整型中&#xff0c;您需要把 long 类型强制转换为 int 类型。您可以使用强制类型转换运算符来把值显式地从一种类型转换为…

【深度学习】BERT变体—ALBERT

ALBERT的初衷是想解决BERT中参数量过多的问题&#xff0c;论文全称为&#xff1a;ALBERT: A Lite BERT for Self-supervised Learning of Language Representations。 相较于BERT&#xff0c;ALBERT模型减少BERT模型的参数量&#xff1b;预训练中的Next Sentence Prediction&a…

【面试系列】线程相关的面试题集锦

线程的状态 public enum State {/*** Thread state for a thread which has not yet started.*/NEW,/*** Thread state for a runnable thread. A thread in the runnable* state is executing in the Java virtual machine but it may* be waiting for other resources from …

最简单的线性回归模型-标量

首先考虑yyy为标量&#xff0c;www为标量的情况&#xff0c;那么我们的线性函数为ywxbywxbywxb。每批输入的量batch size 为111&#xff0c;每批输入的xxx为一个标量&#xff0c;设为x∗x^*x∗&#xff0c;标签yyy同样为一个标量&#xff0c;设为y∗y^*y∗。因此每批训练的损失…

直线模组的优势是什么?

直线模组是可以模拟人工操作的一些功能&#xff0c;通过固定程序来进行抓取&#xff0c;搬运、操作工具&#xff0c;实现自动变速&#xff0c;这也是为何直线模组使用率高的主要原因了&#xff0c;那么直线模组究竟有着怎样的优势呢&#xff1f; 1、整体结构紧凑&#xff0c;重…

k8s-Kubernetes集群部署

文章目录前言一、Kubernetes简介与架构1.Kubernetes简介2.kubernetes设计架构二、Kubernetes集群部署1.集群环境初始化2.所有节点安装kubeadm3.拉取集群所需镜像3.集群初始化4.安装flannel网络插件5.扩容节点6.设置kubectl命令补齐前言 一、Kubernetes简介与架构 1.Kubernetes…

Spark 磁盘作用

Spark 磁盘作用磁盘作用性能价值失败重试ReuseExchangeSpark 导航 磁盘作用 临时文件、中间文件、缓存数据&#xff0c;都会存储到 spark.local.dir 中 在 Shuffle Map 时&#xff0c; 当内存空间不足&#xff0c;就会溢出临时文件存储到磁盘上溢出的临时文件一起做归并计算…

Vue3---语法初探

目录 hello world 实现简易计时显示 反转字符串 显示隐藏 了解循环 了解双向绑定实现简易记事 设置鼠标悬停的文本 组件概念初探&#xff0c;进行组件代码拆分 hello world 最原始形态&#xff0c;找到 id 为 root 的标签&#xff0c;将 Vue 实例的模板放入标签之内 …

剑指 Offer 09. 用两个栈实现队列(java)

用两个栈实现一个队列。队列的声明如下&#xff0c;请实现它的两个函数 appendTail 和 deleteHead &#xff0c;分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素&#xff0c;deleteHead 操作返回 -1 ) 示例 1&#xff1a; 输入&#xff1a; [“CQu…

SpringBoot中一行代码解决字符串向枚举类型转换的问题

1. 场景 在WEB开发&#xff0c;客户端和服务端传输的数据中经常包含一些这样的字段&#xff1a;字段的值只包括几个固定的字符串。 这样的字段意味着我们需要在数据传输对象&#xff08;Data Transfer Object, DTO&#xff09;中对该字段进行校验以避免客户端传输的非法数据持…

Android Service知识

一. 概览 Service 是一种可在后台执行长时间运行操作而不提供界面的应用组件。服务可由其他应用组件启动&#xff0c;而且即使用户切换到其他应用&#xff0c;服务仍将在后台继续运行。此外&#xff0c;组件可通过绑定到服务与之进行交互&#xff0c;甚至是执行进程间通信 (IPC…

你是真的“C”——为冒泡排序升级赋能!

你是真的“C”——为冒泡排序升级赋能&#xff01;&#x1f60e;前言&#x1f64c;冒泡排序升级赋能之境界一&#xff01;冒泡排序升级赋能之境界二&#xff01;qsort库函数的运用和认识总结撒花&#x1f49e;&#x1f60e;博客昵称&#xff1a;博客小梦 &#x1f60a;最喜欢的…

【CDP】更改solr 存储路径导致ranger-audit 大量报错问题解决

前言 我们生产上公司是使用的CDP集群&#xff0c;一次管理员通知&#xff0c;Solr 组件的数据存放路径磁盘空间不够。 我们的solr 组件时为 Ranger 服务提供日志审计功能&#xff0c; 在我们更改了磁盘路径&#xff0c;并重启了Solr 组件&#xff0c;然后发现相关组件&#…

基于Python的selenium

一、安装 1.1安装Python&#xff0c;安装Python时需要勾选增加环境变量 如果之前已经安装过Python&#xff0c;需要将Python相关文件以及环境变量删除 1.2安装成功&#xff1a;在命令行界面下输入Python&#xff0c;最终展示>>>即可成功 2.1安装pycharm,直接自定义安装…

论文阅读-(GLIP)Grounded Language-Image Pre-training (目标检测+定位)

Paper&#xff1a;Grounded Language-Image Pre-training Code&#xff1a;https://github.com/microsoft/GLIP 简介&#xff1a; 定位任务与图像检测任务非常类似&#xff0c;都是去图中找目标物体的位置&#xff0c;目标检测为给出一张图片找出bounding box&#xff0c;定位…

07react+echart,大屏代码开发

react框架引入第三方插件原链接gitHub:GitHub - hustcc/echarts-for-react: ⛳ Apache ECharts components for React wrapper. 一个简单的 Apache echarts 的 React 封装。import ReactECharts from echarts-for-react;import * as echarts from echarts;一、软件简介echarts-…

微机原理和计算机组成原理复习

1&#xff1a;冯诺依曼机器的主要特点&#xff1f; 1&#xff09;计算机由运算器、存储器、控制器、输入设备和输出设备五大部分组成&#xff1b; 2&#xff09;指令和数据存储在存储器中&#xff0c;并可以按地址访问&#xff1b; 3&#xff09;指令和数据均以二进制表示&…

2023年软考中级信息安全工程师考什么?

信息安全工程师是属于软考中级科目&#xff0c;含金量很高的&#xff0c;信息安全工程师在社会上的需求是蛮大的。 信息安全工程师主要涉及计算机信息安全方面&#xff0c;在计算机软硬件、网络、应用相关领域从事安全系统设计、安全产品开发、产品集成、信息系统安全检测与审计…