算法13、基础二分查找的应用(木根切割等)

🌰1、方程求根

晴问算法

  1️⃣即求f(x) = x^3 + x^2 + x - a = 0的根,又因为要求精确到0.01,所以eps至少设置为1e-3或者更小;

  2️⃣求导得3x^2 + 2x + 1 = 2x^2 + x^2 + 2x + 1 = 2x^2 + (x+1)^2  > 0, 所以f(x)是单调递增函数;

  3️⃣估计查找区间初值:因为a的取值区间是-100-100,所以我们让查找区间的初值为【-100 , 100】

这样一定能包含所有可能的解。

  对于闭区间【left, right]:

        若f(mid) > 0,说明mid比解大,则让right = mid;

        若 < 0, 说明mid比解小,则让left = mid;

  当right - left <= eps 则可跳出循环。返回left or mid, 即进入循环条件是right-left > eps,最终取两位小数输出

#include <iostream>
using namespace std;
const double EPS = 1e-3;//
int a;
double f(double x){
    return x*x*x + x*x + x -a ;
}
double binarySearch() {
    double left = -100, right = 100, mid;
    while (right - left > EPS) {
         mid = (left + right) / 2;
        if (f(mid) > 0) {
            right = mid;
        } else {
            left = mid;
        }
    }
    return left;//or mid,但是运行时间会更长。
}

int main() {
    cin >> a;
    printf("%.2f", binarySearch());
    return 0;
}

 🌰2、装水问题

晴问算法

1️⃣我们要求h,所以应当对h进行二分查找,又要求精确到2位小数,所以eps至少是1e-3;

2️⃣又显然随着h的增大,s1的面积也增大,所以当我们对h进行二分查找时,

        若s1/s2 > r说明s1过大了,应该缩小右边界,即让right = mid;

        若s1/s2 < r说明s1过小了,应该扩大左边界,即让left = mid;

当right - left <= eps,就找到了满足要求的解,跳出循环。返回左边界。输出带前2位小数的格式。

3️⃣二分查找区间的初值应该是[0, R], 因为它覆盖了h所有可能的取值。

为了统一代码,我们定义函数f(R, h) = s1/s2

#include <cstdio>
#include <cmath>
const double EPS = 1e-3;
const double PI = acos(-1.0);
double f(double R, double h) {
    double alpha = 2 * acos((R - h) / R);
    double L = 2 * sqrt(R * R - (R - h) * (R - h));
    double S1 = alpha * R * R / 2 - L * (R - h) / 2;
    double S2 = PI * R * R / 2;
    return S1 / S2;
}
double binarySearch(double R, double r){
    double left = 0, right = R, mid;
    while(right - left > EPS){
        mid = (left + right) / 2;
        if(f(R, mid) > r)
            right = mid;
        else
            left = mid;
    }
    return left;
}
int main(){
    int R;
    double r;
    scanf("%d%lf", &R, &r);
    printf("%.2lf\n", binarySearch(R, r));
}

🌰3、木棒切割问题

晴问算法

做法1-转化为基础二分查找

对切割后的长度l进行二分查找,设k为长度l下可得到的最大段数。

  转化思路:
        要求得到的段数至少K段,那么求最大长度也就是求:最后一个满足k>=K的length,再转化一下,就是求:第一个满足k<K的length, 再减1。这样就可以运用基础二分查找的思路找到第一个满足k<K的length了:

对于二分查找区间[left, right]:

        若k < K,说明mid有可能是解,但还需往左寻找,因为要求第一个满足k<K的length,那就让right = mid;

        若k >= K, 说明k过大,也就是length过小,那么就让left = mid + 1;

当left == right则找到了解,所以进入循环的条件是left < right.

  ⚠️除数不能为0:

  二分查找区间的初值本应该是[0, max(a[i]) ],即若返回值是0(0-1==-1)或者1(1-1==0),都说明无法达成,都应该输出0,所以应该额外判断返回值为0时,直接输出0不要再-1了。

  但是,由于计算当前mid可得到的最大段数用到了除法,除数length不能为0,

  因此,查找区间的初值应该从1开始,保证除数不会为0,即left应初始化为1.这样,最后就能够统一输出返回值-1,不需要额外判断返回值了。

返回left or right,最后将返回值-1得到最终结果。

#include <iostream>
using namespace std;
const int MAXN = 1005;
int a[MAXN];//存木棒长度
int n, K;
int Num(int length){
    int ans = 0;
    for(int i = 0; i < n; i++)
        ans += a[i] / length;//注意除法要求除数不为0!!
    return ans;
}
int binarySearch(int right){
    int left = 1, mid;
    while(left < right){
        mid =  (left + right ) / 2;
        if(Num(mid) < K)
            right = mid;
        else 
            left = mid + 1;
    }
    return left;// or right;
}
int main(){
    cin >> n >> K;
    int maxL = 0;
    for(int i = 0; i < n; i++){
        cin >> a[i];
        if(a[i] > maxL)
            maxL = a[i];
    }
    printf("%d\n", binarySearch(maxL)-1 );
}
做法2

  1️⃣题目要求切割后每根木棒的最大长度,那么就应该对切割后每根木棒的长度进行二分查找,那么查找区间初值为[0,max(木棒长度)]

  2️⃣又显然,要求切割后得到的木棒段数越多即k越大,长度就会越小,设函数Num(l)为长度为l时可得到的最多段数

对于二分查找区间[left, right]:

        若Num(mid) < k, 不满足至少k段的条件,说明mid不可能是解,且应该让k大一些,那就应该让mid小一点,即让right = mid -1;

        若Num(mid) >= k,满足至少k段的条件,说明mid有可能是解,但还需让mid大一点继续往右检查看是否还有更长的mid满足至少k段,那就让left = mid;

当left == right说明找到了最大长度即解,因此进入循环的条件应该是left < right;

最终应该返回left或者right;

Num(int length) = a1 / length + a2 / length + ……

注意,计算mid时,为了防止left=0,right=1时, 此时mid==0进入Num函数导致的除数为0,应该在此加上1再除以2,

        而且,若没加上1时,当right = left + 1时,设此时left = x, 那么mid = (left + right) /2会等于left==x, 若此时num(mid) >= k那么left = mid == x, 进入下一个循环又是mid=left==x, mid,left就会一直相等num(mid)结果一直不变导致死循环。

#include <iostream>
using namespace std;
const int MAXN = 1005;
int a[MAXN];//存木棒长度
int n, k;
int Num(int length){
    int ans = 0;
    for(int i = 0; i < n; i++)
        ans += a[i] / length;//注意除法要求除数不为0!!
    return ans;
}
int binarySearch(int right){
    int left = 0, mid;
    while(left < right){
        mid =  (left + right + 1) / 2;
        if(Num(mid) < k)
            right = mid - 1;
        else 
            left = mid;
    }
    return left;// or right;
}
int main(){
    cin >> n >> k;
    int maxL = 0;
    for(int i = 0; i < n; i++){
        cin >> a[i];
        if(a[i] > maxL)
            maxL = a[i];
    }

    printf("%d\n", binarySearch(maxL));
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Maven 详细配置:Maven settings 配置文件的详细说明

Maven settings 配置文件是 Maven 环境的重要组成部分&#xff0c;它用于定义用户特定的配置信息和全局设置&#xff0c;例如本地仓库路径、远程仓库镜像、代理服务器以及认证信息等。settings 文件分为全局配置文件&#xff08;settings.xml&#xff09;和用户配置文件&#x…

【C++】18.继承

文章目录 1.继承的概念及定义1.1 继承的概念1.2 继承定义1.2.1定义格式1.2.2继承关系和访问限定符1.2.3继承基类成员访问方式的变化 1.3 继承类模板 2.基类和派生类对象赋值转换3.继承中的作用域3.1 隐藏规则&#xff1a;3.2 考察继承作用域相关选择题 4.派生类的默认成员函数4…

声音是如何产生的

一、音频概述 RTMP中一般音频采用aac编码&#xff0c;采样率为44100HZ, 每帧1024采样&#xff0c;帧率43&#xff0c;23.2ms一帧 RTC中一般音频采用opus编码&#xff0c;采样率为48000HZ&#xff0c;每帧480采样&#xff0c;帧率100&#xff0c;10ms一帧 通道数&#xff08;c…

什么是中间件中间件有哪些

什么是中间件&#xff1f; 中间件&#xff08;Middleware&#xff09;是指在客户端和服务器之间的一层软件组件&#xff0c;用于处理请求和响应的过程。 中间件是指介于两个不同系统之间的软件组件&#xff0c;它可以在两个系统之间传递、处理、转换数据&#xff0c;以达到协…

问题清除指南|关于num_classes与 BCELoss、BCEWithLogitsLoss 和 CrossEntropyLoss 的关系

前言&#xff1a;关于「 num_classes 1 」引发的探究。 2024年尾声&#xff0c;学弟问到一个问题&#xff1a;在研究工作 CNNDetection 的github开源代码 networks/trainer.py 文件的 line 27 self.model resnet50(num_classes1) 中&#xff0c;变量 num_classes 的值为1&…

FinDKG: 用于检测金融市场全球趋势的动态知识图谱与大型语言模型

“FinDKG: Dynamic Knowledge Graphs with Large Language Models for Detecting Global Trends in Financial Markets” 论文地址&#xff1a;https://arxiv.org/pdf/2407.10909 摘要 动态知识图&#xff08;DKG&#xff09;能够表示对象间随时间变化的关系&#xff0c;适用于…

Robot---奇思妙想轮足机器人

1 背景 传统机器人有足式、轮式、履带式三种移动方式&#xff0c;每种移动方式都有各自的优缺点。轮式机器人依靠车轮在地面上移动&#xff0c;能源利用率高、移动速度快&#xff0c;但是仅以轮子与地面接触&#xff0c;缺乏越障能力和对复杂地形的适应能力&#xff0c;尤其面对…

高效工作流:用Mermaid绘制你的专属流程图;如何在Vue3中导入mermaid绘制流程图

目录 高效工作流&#xff1a;用Mermaid绘制你的专属流程图 一、流程图的使用场景 1.1、流程图flowChart 1.2、使用场景 二、如何使用mermaid画出优雅的流程图 2.1、流程图添加图名 2.2、定义图类型与方向 2.3、节点形状定义 2.3.1、规定语法 2.3.2、不同节点案例 2.…

.NET框架用C#实现PDF转HTML

HTML作为一种开放标准的网页标记语言&#xff0c;具有跨平台、易于浏览和搜索引擎友好的特性&#xff0c;使得内容能够在多种设备上轻松访问并优化了在线分享与互动。通过将PDF文件转换为HTML格式&#xff0c;我们可以更方便地在浏览器中展示PDF文档内容&#xff0c;同时也更容…

Tableau数据可视化与仪表盘搭建-可视化原则及BI仪表盘搭建

目录 可视化原则 BI仪表盘搭建 仪表盘搭建原则 明确仪表盘主题 仪表盘主题拆解 开发设计工作表 经营情况总览&#xff1a;突出显示的文字 经营数据详情&#xff1a;表格 每日营收数据&#xff1a;多轴折线图 每日流量数据&#xff1a;双轴组合图 新老客占比&#xf…

AIA - APLIC之三(附APLIC处理流程图)

本文属于《 RISC-V指令集基础系列教程》之一,欢迎查看其它文章。 1 APLIC复位 APLIC复位后,其所有状态都变得有效且一致,但以下情况除外: 每个中断域的domaincfg寄存器(spec第 4.5.1 节);可能是machine-level interrupt domain的MSI地址配置寄存器(spec第4.5.3 和4.5…

unity学习5:创建一个自己的3D项目

目录 1 在unity里创建1个3D项目 1.1 关于选择universal 3d&#xff0c;built-in render pipeline的区别 1.2 创建1个universal 3d项目 2 打开3D项目 2.1 准备操作面板&#xff1a;操作界面 layout,可以随意更换 2.2 先收集资源&#xff1a;打开 window的 AssetStore 下载…

AI赋能跨境电商:魔珐科技3D数字人破解出海痛点

跨境出海进入狂飙时代&#xff0c;AI应用正在深度渗透并重塑着跨境电商产业链的每一个环节&#xff0c;迎来了发展的高光时刻。生成式AI时代的大幕拉开&#xff0c;AI工具快速迭代&#xff0c;为跨境电商行业的突破与飞跃带来了无限可能性。 由于跨境电商业务自身特性鲜明&…

我用Ai学Android Jetpack Compose之Text

这篇开始学习各种UI元素&#xff0c;答案来自 通义千问&#xff0c;通义千问没法生成图片&#xff0c;图片是我补充的。 下述代码只要复制到第一个工程&#xff0c;做一些import操作&#xff0c;一般import androidx.compose包里的东西&#xff0c;即可看到预览效果。完整工程代…

HashMap总结使用+原理+面试

文章目录 1.Hashmap的基本使用创建hashmap对象。遍历hashmap统计字母出现的次数用来投票计算返回JSON数据 2.hashmap源码阅读put源码阅读 3. HashMap 面试题目hashmap实现的原理什么时候数组需要进行扩容hashmap怎么确定把数据放到那个节点的哪个位置。为什么用 n - 1 与运算&a…

JS中函数基础知识之查漏补缺(写给小白的学习笔记)

函数 函数是ECMAScript中 最有意思的部分之一, 主要是因为函数实际上是对象.-- 每个函数 都是Function类型的实例,Function也有属性和方法. 因为函数是对象,所以函数名就是指向函数对象的指针. 常用的定义函数的语法: ①函数声明 ②函数表达式 ③箭头函数 function sum (n…

Skyeye 云 VUE 版本 v3.15.3 发布,涉及 ERP、OA、财务等

Skyeye 云智能制造&#xff0c;采用 Springboot winUI 的低代码平台、移动端采用 UNI-APP。包含 30 多个应用模块、50 多种电子流程&#xff0c;CRM、PM、ERP、MES、ADM、EHR、笔记、知识库、项目、门店、商城、财务、多班次考勤、薪资、招聘、云售后、论坛、公告、问卷、报表…

LInux单机安装Redis

1. 安装gee工具包 由于Redis是基于c语言编写的所以安装的时候需要先安装gee以及gcc的依赖,yum云用不了可以看一下这个 linux 替换yum源镜像_更换yum镜像源-CSDN博客 yum install -y gcc tcl 2. 添加redis的压缩包 3. 上传到Linux 上传到 /usr/local/src 目录、这个目录一般用于…

热备份路由HSRP及配置案例

✍作者&#xff1a;柒烨带你飞 &#x1f4aa;格言&#xff1a;生活的情况越艰难&#xff0c;我越感到自己更坚强&#xff1b;我这个人走得很慢&#xff0c;但我从不后退。 &#x1f4dc;系列专栏&#xff1a;网路安全入门系列 目录 一&#xff0c;HSRP的相关概念二&#xff0c;…

java开发springoot

阅读理解 命令之间空一行&#xff1a;表示前面的是配置 红色背景&#xff1a;表示待验证蓝色背景&#xff1a;表示常用或推荐绿色背景&#xff1a;注意/推荐 json 转 对象 import com.fasterxml.jackson.databind.ObjectMapper; public DebangResp convertJsonToObject(Stri…