《从入门到精通:蓝桥杯编程大赛知识点全攻略》(五)-数的三次方根、机器人跳跃问题、四平方和

本博客将详细探讨如何通过二分查找算法来解决这几个经典问题。通过几个实际的例子,我们将展示如何在这些问题中灵活应用二分查找,优化计算过程,并在面对大数据量时保持高效性。

目录

前言

数的三次方根

算法思路

代码如下

机器人跳跃问题

算法思路

代码如下

 四平方和

算法思路

 代码如下

总结


前言

本博客将详细探讨如何通过二分查找算法来解决这几个经典问题。通过几个实际的例子,我们将展示如何在这些问题中灵活应用二分查找,优化计算过程,并在面对大数据量时保持高效性。


数的三次方根

给定一个浮点数 n,求它的三次方根。

输入格式

共一行,包含一个浮点数 n。

输出格式

共一行,包含一个浮点数,表示问题的解。

注意,结果保留 6 位小数。

数据范围

−10000≤n≤10000

输入样例:

1000.00

输出样例:

10.000000

算法思路

这道题题很多思路。 这次主要通过二分来进行处理,锻加强二分的练习。设置两个double类型变量lleft = -10000,right = 10000;取中间值mid,当mid * mid * mid >= x的时候,说明右区间的值太大,在[left,mid]中寻找。如果mid * mid * mid < x,说明需要在(mid,right]区间里面找,最后的答案输出left或者right都可。(注意题目精度,结果要6位小数,那么循环判断的时候增加两位精度即1e-8即可)

代码如下

import java.io.*;public class Main {static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));static StreamTokenizer st = new StreamTokenizer(br);public static void main(String[] args)throws Exception {double x = nextDouble();double left  = -10000;double right = 10000; while (right - left > 1e-8) { //1e-8表示的题目精度,随题目变化而变化,一般比所求答案高两个精度double mid = (left + right) / 2;if(mid * mid * mid >= x){right = mid;}else {left = mid;}}pw.printf("%.6f", right);pw.flush();}public static double nextDouble()throws Exception{st.nextToken();return (double)st.nval;}
}

机器人跳跃问题

机器人正在玩一个古老的基于 DOS 的游戏。

游戏中有 N+1 座建筑——从 0到 N 编号,从左到右排列。

编号为 0 的建筑高度为 0个单位,编号为 i 的建筑高度为 H(i) 个单位。

起初,机器人在编号为 0 的建筑处。

每一步,它跳到下一个(右边)建筑。

假设机器人在第 k 个建筑,且它现在的能量值是 E,下一步它将跳到第 k+1个建筑。

如果 H(k+1)>E,那么机器人就失去 H(k+1)−E 的能量值,否则它将得到 E−H(k+1)的能量值。

游戏目标是到达第 N 个建筑,在这个过程中能量值不能为负数个单位。

现在的问题是机器人至少以多少能量值开始游戏,才可以保证成功完成游戏?

输入格式

第一行输入整数 N。

第二行是 N 个空格分隔的整数,H(1),H(2),…,H(N) 代表建筑物的高度。

输出格式

输出一个整数,表示所需的最少单位的初始能量值上取整后的结果。

数据范围

1≤N,H(i)≤10^5

输入样例1:

5
3 4 3 2 4

算法思路

 根据图示的推论 可知,其实无论哪一种情况最后E能量的变化都为2*E-h(i);与此同时当我们发现,如果E满足题意,那么E1 >= E,那么E1也是满足题意的。此时答案E就具有的单调性。

根据图示的推论,那么我们就知道答案E的最大值一定不超过100000,最小值大于等于0;可以用二分的方式来进行计算。

用整型数组arr记录每个建筑的能量值,用整型变量n来记录建筑数,左边界left = 0;右边界right = 100000;当left < right时,开始循环,找到中间值mid = (left + right) / 2;然后检查此时的mid值是否符合要求;

检查函数check,传过来的值E能量,然后从1遍历到n,计算e = 2 * e - arr[i];然后判断此时的e是否小于0,小于0直接不符合要求,返回false;当e >= 100000时,相当于满足题意了,一定成功可以提前返回true。循环结束时,返回true,表示满足题意。

当判断mid为true时说明此时的区间(mid,right]区间内,一定是E的值比mid大,最后答案要的是mid的最小值,说明右区间不可能存在,故右边界左移即right = mid;当mid不合格,说明区间[left,mid]中所有的E都不符合题意,故正确答案一定在右区间,所以左区间右移即left = mid + 1;最后输出left即为最后的答案。

代码如下


import java.io.*;
public class Main {static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));static StreamTokenizer st = new StreamTokenizer(br);static int N = 100010;static int[] arr = new int[N];static int n;public static void main(String[] args)throws Exception {n = nextInt();for (int i = 1; i <= n; i++) {arr[i] = nextInt();}int left = 0;int right =100000;while (left < right) {int mid = (left + right) / 2;if(check(mid)){right = mid;}else {left = mid + 1;}}pw.println(left);pw.flush();}public static boolean check(int e){for(int i = 1;i <= n;i++){e = e * 2 - arr[i];//只要大于等于e的最大值,那么必然符合条件if(e >= 100000){return true;}if(e < 0){return false;}}return true;}public static int nextInt()throws Exception {st.nextToken();return (int) st.nval;}
}

 四平方和

四平方和定理,又称为拉格朗日定理:

每个正整数都可以表示为至多 4 个正整数的平方和。

如果把 0 包括进去,就正好可以表示为 4 个数的平方和。

比如:

5=0^{2}+0^{2}+1^{2}+2^{2}

7 = 1^{2}+1^{2}+1^{2}+2^{2}

对于一个给定的正整数,可能存在多种平方和的表示法。

要求你对 4 个数排序:

0≤a≤b≤c≤d

并对所有的可能表示法按 a,b,c,d 为联合主键升序排列,最后输出第一个表示法。

输入格式

输入一个正整数 N。

输出格式

输出4个非负整数,按从小到大排序,中间用空格分开。

数据范围

0<N<5*10^6

输入样例:

5

输出样例:

0 0 1 2

算法思路

暴力做法直接枚举前3个数a、b、c,最后一个d可以直接算d = \sqrt{n - a^{2}- b^{2}-c^{2}},因为d是算出来的,可能为小数,还需判断一下 d^{2} == n - a^{2}-b^{2}-c^{2},当条件成立是就是最后的答案。(但这道题枚举3层循环会超时。)

二分优化做法。

先枚举所有c、d的情况,然后将c、d、c*c+d*d 3个值存起来,再去枚举a、b的情况,然后将 t = n - a * a - b * b与对应的c*c+d*d做对比,找出正确的答案。

引入整型变量n才存储最后的结果,用两层循环来枚举c和d,用一类内部类Sum来存储c、d和sum(存储c*c+d*d);每枚举一个c和d,将3个值存储list列表。循环结束后,按照宿命从小到大,当sum相同时按照c从小到大,当c相同时按照d从小到大。

然后再用两次循环枚举a和b,用整型变量t来存储n - a * a - b * b;用二分来查找,左边界left0,右边界list列表的长度-1;当列表list中的下标为mid的sum >= t,此时说明答案在左区间,此时右边界左移right = mid;当list中的下标为mid的sum < t,说明答案在右区间且不包括下标为mid,所以左区间右移即left = mid + 1;最后list中的下标为left的sum等于t时,此时得到的a、b、c、d就是最后的答案。

 代码如下

暴力做法

public class 四平方和 {static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));static StreamTokenizer st = new StreamTokenizer(br);static int n;public static void main(String[] args)throws Exception {n = nextInt();for(int a = 0; a * a <= n;a++){for(int b = 0;b * b + a * a <= n;b++){for(int c = b; c * c + b * b + a * a <= n;c++ ){int t = n - a * a - b * b - c * c;int d =(int) Math.sqrt(t);if(d * d == t){pw.println(a+" "+b+" "+c+" "+d);pw.flush();return;}}}}}public static int nextInt()throws Exception {st.nextToken();return (int)st.nval;}

 二分优化


import java.io.*;
import java.util.*;public class Main {static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));static StreamTokenizer st = new StreamTokenizer(br);static List<Sum> list = new ArrayList();static int n;public static void main(String[] args)throws Exception {n = nextInt();for(int c = 0; c * c <= n;c++){for(int d = c;c * c + d * d <= n;d++){list.add(new Sum(c * c + d * d,c,d));}}//字典序排序 lambda表达式list.sort((sum1,sum2)->{if(sum1.sum != sum2.sum) return sum1.sum - sum2.sum;if(sum1.c != sum2.c) return sum1.c - sum2.c;return sum1.d - sum2.d;});for(int a = 0; a * a <= n;a++){for(int b = a;b * b + a * a <= n;b++){int t = n - a * a -b * b;int left = 0;int right = list.size() - 1;while(left < right){int mid = (left + right)/2;if(list.get(mid).sum >= t){right = mid;}else {left = mid + 1;}}if(list.get(left).sum == t){pw.println(a+" "+b+" "+list.get(left).c+" "+list.get(left).d);pw.flush();return;}}}pw.flush();}public static int nextInt()throws Exception {st.nextToken();return (int)st.nval;}
}
class Sum{int sum;//c^2 + d^2 = sumint c;int d;public Sum(int sum, int c, int d) {this.sum = sum;this.c = c;this.d = d;}
}

总结

二分查找不仅仅是一种简单的查找方法,它在很多复杂问题中都有着非常广泛的应用。掌握二分查找的技巧,将帮助我们在面对各种挑战时,能够快速并准确地找到答案。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务知识——4大主流微服务架构方案

文章目录 1、微服务聚合模式2、微服务共享模式3、微服务代理模式4、微服务异步消息模式 微服务是大型架构的必经之路&#xff0c;也是大厂重点考察对象&#xff0c;下面我就重点详解4大主流微服务架构方案。 1、微服务聚合模式 微服务聚合设计模式&#xff0c;解决了如何从多个…

麒麟操作系统服务架构保姆级教程(十三)tomcat环境安装以及LNMT架构

如果你想拥有你从未拥有过的东西&#xff0c;那么你必须去做你从未做过的事情 之前咱们学习了LNMP架构&#xff0c;但是PHP对于技术来说确实是老掉牙了&#xff0c;PHP的市场占有量越来越少了&#xff0c;我认识一个10年的PHP开发工程师&#xff0c;十年工资从15k到今天的6k&am…

游戏AI,让AI 玩游戏有什么作用?

让 AI 玩游戏这件事远比我们想象的要早得多。追溯到 1948 年&#xff0c;图灵和同事钱伯恩共同设计了国际象棋程序 Turochamp。之所以设计这么个程序&#xff0c;图灵是想说明&#xff0c;机器理论上能模拟人脑能做的任何事情&#xff0c;包括下棋这样复杂的智力活动。 可惜的是…

Golang的文件处理优化策略

Golang的文件处理优化策略 一、Golang的文件处理优化策略概述 是一门效率高、易于编程的编程语言&#xff0c;它的文件处理能力也非常强大。 在实际开发中&#xff0c;需要注意一些优化策略&#xff0c;以提高文件处理的效率和性能。 本文将介绍Golang中的文件处理优化策略&…

数据结构学习记录-队列

队列的基本概念 1、队列是操作受限的线性表 2、队头&#xff1a;允许删除的一端 3、队尾&#xff1a;允许插入的一端 4、空队列&#xff1a;不含任何元素的空表 5、特点&#xff1a;先进先出、FIFO 6、应用场景&#xff1a; 栈&#xff1a;解决括号匹配&#xff1b;逆波…

java知识框架

面试1 基础篇 如何理解OOP面向对象编程&#xff1f; 对现有事物进行抽象&#xff0c;具有继承、封装、多态的特征。 继承&#xff1a;从已有的类也就是父类进行继承信息。 封装&#xff1a;对数据和数据操作的方法绑定起来&#xff0c;通过方法进行访问或者操作数据。 多态…

JDBC实验测试

一、语言和环境 实现语言&#xff1a;Java。 环境要求&#xff1a;IDEA2023.3、JDK 17 、MySQL8.0、Navicat 16 for MySQL。 二、技术要求 该系统采用 SWING 技术配合 JDBC 使用 JAVA 编程语言完成桌面应用开发。 三、功能要求 某电商公司为了方便客服查看用户的订单信…

小程序获取微信运动步数

1、用户点击按钮&#xff0c;在小程序中触发getuserinfo方法&#xff0c;获取用户信息 <scroll-view class"scrollarea" scroll-y type"list"><view class"container"><button bind:tap"getLogin">获取</button&…

macOS 安装JDK17

文章目录 前言介绍新特性下载安装1.下载完成后打开downloads 双击进行安装2.配置环境变量3.测试快速切换JDK 小结 前言 近期找开源软件&#xff0c;发现很多都已经使用JDK17springboot3 了&#xff0c;之前的JDK8已经被替换下场&#xff0c;所以今天就在本机安装了JDK17&#…

Windows电脑桌面记录日程安排的提醒软件

在快节奏的现代生活中&#xff0c;工作效率成为了衡量个人能力的重要标准之一。然而&#xff0c;日常办公中常常会遇到各种琐事和任务&#xff0c;如果没有合理安排日程&#xff0c;很容易陷入混乱&#xff0c;导致效率低下。因此&#xff0c;做好日程安排对于日常工作至关重要…

MFC 使用 32位带Alpha通道的位图

最近需要做一个MFC界面上的图片,众所周知,MFC 好像只支持 bmp 格式的! 先看我的原始24位图片,RGB 三个颜色各占8位 (256色), 所以是24位。 如果放到MFC界面上,是这个很丑的效果 它是一个正方形图片,周围的白色可以看见。 解下来,进入今天的主题: 32位带 Alpha 通…

Ubuntu22部署MySQL5.7详细教程

Ubuntu22部署MySQL5.7详细教程 一、下载MySQL安装包二、安装MySQL三、启动MySQL 检查状态登录MySQL 四、开启远程访问功能 1、允许其他主机通过root访问数据库2、修改配置文件&#xff0c;允许其他IP通过自定义端口访问 五、使用Navicat连接数据库 默认情况下&#xff0c;Ubun…

大模型 | AI驱动的数据分析:利用自然语言实现数据查询到可视化呈现

【本文作者&#xff1a;擎创科技资深产品专家 布博士】 在当今AI驱动的时代&#xff0c;数据分析已成为各行各业不可或缺的能力。然而&#xff0c;传统的数据分析流程通常需要掌握SQL、数据处理和可视化等多项专业技能&#xff0c;这对非技术背景的业务人员来说是一个不小的挑…

C++ ——— 模拟实现 vector 类

目录 vector 类的框架 无参数的构造函数 析构函数 获取有效数据个数 获取容量 重载 [] 运算符 可读可写版本 只可读版本 扩容 尾插 实现迭代器 可读可写版本 只可读版本 自定义设置size长度和内容 在任意位置插入 删除任意位置的数据 赋值重载 vector 类的框…

Git处理冲突详解

文章目录 Git处理冲突详解一、引言二、冲突产生的原因三、解决冲突的步骤1. 手动解决冲突1.1 查看冲突文件1.2 编辑冲突文件1.3 提交解决冲突 2. 使用合并工具解决冲突 四、使用示例五、总结 Git处理冲突详解 一、引言 在团队协作开发中&#xff0c;Git冲突是不可避免的。当多…

GS论文阅读--GeoTexDensifier

前言 本文是一个关于高斯致密化策略对高斯地图进行优化&#xff0c;他主要关注了几何结构和纹理信息。我最近对于高斯点的分布比较感兴趣&#xff0c;因为高斯点的分布决定了之后重建质量的好坏&#xff0c;初始化高斯很重要&#xff0c;但之后的维护需要致密化与修建策略&…

【云原生布道系列】第三篇:“软”饭“硬”吃的计算

1 虚拟化技术定义 首先援引一段《虚拟化技术发展编年史》中针对虚拟化技术的定义&#xff1a;在计算机科学中&#xff0c;虚拟化技术&#xff08;Virtualization&#xff09;是一种资源管理&#xff08;优化&#xff09;技术&#xff0c;将计算机的各种物理资源&#xff08;例如…

Java虚拟机面试题:内存管理(中)

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

Linux容器(初学了解)

目录 一、容器 1.1、容器技术 1.2、容器和虚拟机之间的差异 1.3、Rootless 和 Rootful 容器 1.4、设计基于容器的架构 1.5、容器管理工具 1.6、容器镜像和注册表 1.7、配置容器注册表 1.8、使用容器文件构建容器镜像 二、部署容器 2.1、Podman 实用程序 2.2、安装容…

代码随想录_字符串

字符串 344.反转字符串 344. 反转字符串 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须**原地修改输入数组**、使用 O(1) 的额外空间解决这一问题。 思路: 双指针 代…