蓝桥杯倒计时48天!二分模板

倒计时48天!

二分

二分模板
判断是否可以二分

(1)单调性

备选答案集是有序的

(2)二段性

在检查了mid是否符合要求之和,我可以舍弃mid左右某一边的答案

两个模板
  1. 关键词:满足条件的最小值,最大值最小,某个有序区间内某个数>=或者>key的第一个元素,或者当正确答案在左边时

    while(l < r) {//check函数求当前值为mid情况下是否合法,如果合法,会想更小一点的值是不是合法的,所以会舍弃掉右边,去左边寻找更小的值,即r向左移动,因为mid是合法的,不能不要它,所以r=midif(check(mid)) {//满足要求,要求最小,再向左找看有没有更小的也满足要求r = mid;//因为mid也满足要求,所以要保留//如果不合法,只能扩大当前值,所以会舍弃掉左边,去右边寻找更大的值,即l向右移动,因为mid是不合法的,直接不要它,所以l=mid+1}else{l = mid + 1;//mid不满足要求,直接跳过就行}}
    

    假设出现如下情况,l=l,r=l+1,此时mid=l。如果mid = (l+r)/2

    (1)check(mid)返回为真,r = mid = l,正常退出

    (2)check(mid)返回为假,l = r,正常退出

  2. 某个有序区间内某个数<=或者<key的最后一个元素,或者说满足要求的最大,或者当正确答案在右边时

while(l < r) {long mid = (l+r+1)/2;//注意这里要+1if(check(mid)) {//满足要求,要求最大,再向右找看有没有更大的也满足要求l = mid;//因为mid也满足要求,所以要保留}else{r = mid - 1;//mid不满足要求,直接跳过就行}}

对于mid=(l+r)/2,假设出现如下情况,l=l,r=l+1,此时mid=l。如果mid = (l+r)/2

(1)check(mid)返回为真,l = mid = l,此时会陷入无限循环

(2)check(mid)返回为假,r < l,正常退出

对于mid=(l+r+1)/2,假设出现如下情况,l=l,r=l+1,此时mid=l+1。如果mid = (l+r+1)/2

(1)check(mid)返回为真,l = mid = l+1=r,正常退出

(2)check(mid)返回为假,r = l,正常退出

对于这两个模板,不需要硬记,在做题的过程中边分析边写完全没问题,记住如果分析的过程中出现了“—”号,一定要在mid这里除以2的时候加1。可以告诉自己本身(l+r)/2就是下取整,有损失,这里又出现了减法,损失更大了,所以要写成(l+r+1)/2。

分巧克力
题目分析

希望巧克力的边长最大,而巧克力的边长要满足一个条件,就是按照该边长切出来的巧克力的块数应该大于等于K块才能满足K位小朋友都有巧克力。那么现在就是满足条件的最大值,我们要看一下他是否符合二段性,二分的关键在于二段性。

对于边长为mid的巧克力,如果它可以切出k块巧克力,那么我们可以确定边长小于mid的巧克力一定也可以,但是此时我需要找的是最大的边长,那么mid一定比小于mid的值更大,所以小于mid的值我就不用管了,也就是我可以确定我能够舍弃掉mid左边的值。我还想要确定比mid更大的边长是否也满足条件,所以我要在mid的右边继续二分。

对于边长为mid的巧克力,如果它不可以切出k块巧克力,那么我们可以确定边长大于mid的巧克力一定也不可以,所以大于等于mid的值我就不用管了,也就是我可以确定我能够舍弃掉mid右边的值。我还想要寻找比mid更小的边长是否能满足条件,所以我要在mid的左边继续二分。

综上该题满足二段性,可以用二分,二分的板子就不说了,接下来说一下check函数如何写。

check(u)要实现的作用是检查边长为u的情况下能否切出k块巧克力。已知某块巧克力为 W ∗ H W*H WH大小,那么能够切出来的巧克力个数用 ( W / u ) ∗ ( H / u ) (W/u)*(H/u) (W/u)(H/u)表示。注意不能用 ( W ∗ H ) / ( u ∗ u ) (W*H)/(u*u) (WH)/(uu)表示。那么只需要遍历当前每一块巧克力,求出能个切割的巧克力总数和k比较就可以了,代码如下,

private static boolean check(int[][] a, int mid, int k) {int sum = 0;for (int i = 0; i < a.length; i++) {sum =sum + (a[i][0]/mid)*(a[i][1]/mid);}if(sum >= k) {return true;}return false;
}

那么这里的边长的最小值是1,最大值就是巧克力的最大边长,也就是100000。

题目代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();int k = scanner.nextInt();int a[][] = new int[n][2];for (int i = 0; i < n; i++) {a[i][0] = scanner.nextInt();a[i][1] = scanner.nextInt();}int l = 1;int r = 100000;while(l<r) {int mid = (l + r + 1) / 2;if(mid == 1) break;if(check(a,mid,k)) {l = mid;}else {r = mid - 1;}}System.out.println(l);
}private static boolean check(int[][] a, int mid, int k) {int sum = 0;for (int i = 0; i < a.length; i++) {sum =sum + (a[i][0]/mid)*(a[i][1]/mid);}if(sum >= k) {return true;}return false;
}
}
求阶乘
题目分析

如果直接去求,我们看一下,K的范围已经到了 1 18 1^{18} 118,这么大肯定有什么巧妙的地方,而不是直接求解。对于一个数字N而言,我们怎么去求他的阶乘末尾包含0的个数?末尾的0是如何产生的?是不是由 2 ∗ 5 = 10 2*5=10 25=10产生的?我们只需要求N!里面包含几个2或者几个5就行了,那么由2或者5个数的最小值决定末尾0的个数,那么2和5而言,比如1-20里面,5,10,15,20包含5,而2,6,8,10,12,14,16,20里面包含2,也就是5的个数必然比2少,那么只需要求N!里面包含5的个数就可以了。那么这个求法大家可以记住,代码如下,

private static long f(long x) {long res = 0;while(x > 0) {res += x / 5;x = x / 5;}return res;
}

求x!里面包含5的个数,令x/5,直到x的值为0就停止。比如25里面5的个数等于sum+=25/5=sum+=5。25/5=5不等于0,所以还要再来一次sum+=5/5=sum+=1。此时就可以了。那么25里面包含6个5。其中5,10,15,20,都包含1个5,而25里面两个5,所以一共6个5。

我们要求满足N!末尾0的个数恰好为K的最小的N是不是就是求满足条件的最小,还是要考虑一下二分。

如果对于mid!末尾0的个数比K少,那么所有比mid小的值的阶乘包含的5的个数肯定更少,所以我可以把mid左边的值都舍弃掉,继续向mid右边寻找。

如果对于mid!末尾0的个数比K大,那么所有比mid大的值的阶乘包含的5的个数肯定更多,所以我可以把mid右边的值都舍弃掉,继续向mid左边寻找。

综上满足二分的二段性,而check函数就是求解N!里面5的个数,前面已经讲解了。

但是注意这里,我不能确定一定可以找到一个满足条件的解,对于分巧克力那道题,题目说了每个小朋友能够至少获得一块边长为1的巧克力,所以边长为1一定满足条件,一定有解。而本题也说了,这样的N可能不存在,所以在二分结束后,我要确定一下,当前的值是否满足条件。

题目代码
import java.util.Scanner;
public class Main {
public static void main(String[] args) {Scanner scanner = new Scanner(System.in);long k = scanner.nextLong();long l = 1,r = Long.MAX_VALUE-10;while(l < r) {long mid = (l+r)/2;if(f(mid) < k ) {l = mid + 1;}else {r = mid;}}if(f(l) == k) {System.out.println(l);}else {System.out.println(-1);}}private static long f(long x) {long res = 0;while(x > 0) {res += x / 5;x = x / 5;}return res;
}
}

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

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

相关文章

【每日前端面经】2023-02-24

题目来源: 牛客 对Vue的理解 Vue是一款流行的JS前端框架&#xff0c;关注的核心是MVC模式的视图层&#xff0c;能够简化数据更新 Vue的核心是数据驱动、组件化和指令系统 数据驱动: 分为模型层、视图层和视图模型层组件化: 可以把各种逻辑封装进统一组件进行复用指令系统: 当…

【VSCode】SSH Remote 通过跳板机连开发机提示“bash行1 powershell未找到命令”

需求背景 因为需要&#xff0c;在家我需要挂上公司VPN然后SSH连到跳板机&#xff0c;然后再从跳板机SSH进开发机。 问题背景 跳板机进开发机输入完密码显示 bash行1 powershell未找到命令VSCode SSH Remote跳板机配置请自行搜素其他文章config配置 注意其中ssh.exe地址请根据…

Microsoft Edge 越用越慢、超级卡顿?网页B站播放卡顿?

记录10个小妙招 Microsoft Edge 启动缓慢、菜单导航卡顿、浏览响应沉闷&#xff1f;这些情况可能是由于系统资源不足或浏览器没及时更新引起的。接下来&#xff0c;我们将介绍 10 种简单的方法&#xff0c;让 Edge 浏览器的速度重新起飞。 基础检查与问题解决 如果 Microsoft…

基于Python爬虫河南开封酒店数据可视化系统设计与实现(Django框架) 研究背景与意义、国内外研究现状

博主介绍&#xff1a;黄菊华老师《Vue.js入门与商城开发实战》《微信小程序商城开发》图书作者&#xff0c;CSDN博客专家&#xff0c;在线教育专家&#xff0c;CSDN钻石讲师&#xff1b;专注大学生毕业设计教育和辅导。 所有项目都配有从入门到精通的基础知识视频课程&#xff…

并发编程(5)共享模型之不可变

7 共享模型之不可变 本章内容 不可变类的使用不可变类设计无状态类设计 7.1 日期转换的问题 问题提出 下面的代码在运行时&#xff0c;由于 SimpleDateFormat 不是线程安全的, 有很大几率出现 java.lang.NumberFormatException 或者出现不正确的日期解析结果&#xff0c;…

规则持久化(Sentinel)

规则持久化 基于Nacos配置中心实现推送 引入依赖 <dependency><groupId>com.alibaba.csp</groupId><artifactId>sentinel-datasource-nacos</artifactId> </dependency> 流控配置文件 [{"resource":"/order/flow",…

ubuntu压缩和解压

-c 创建 -x 解压 -v 显示过程 -f 文件名 xz格式 tar -tf arm-linux-gnueabi-5.4.0.tar.xz 查看压缩包的内容 tar -xf arm-linux-gnueabi-5.4.0.tar.xz -C / 解压 gz格式 t…

六、Vuex

六、Vuex 6.1 Vuex是什么 概念&#xff1a;专门在 Vue 中实现集中式状态&#xff08;数据&#xff09;管理的一个 Vue 插件&#xff0c;对 vue 应 用中多个组件的共享状态进行集中式的管理&#xff08;读/写&#xff09;&#xff0c;也是一种组件间通信的方 式&#xff0c;且…

vue3获取环境变量import.meta.env

vitevue的时候环境变量的获取方式变成如下&#xff1a; console.log(import.meta.env)

MongoDB之角色与权限及创建用户与授权操作详解

MongoDB之角色与权限及创建用户与授权操作详解 文章目录 MongoDB之角色与权限及创建用户与授权操作详解1. 角色与权限1. 角色分类2. 权限说明 2. MongDB创建用户及删除用户1. 创建用户2. 查看用户信息3. 修改用户密码 3. db.runCommand创建用户与授权1. 创建用户2. 更改用户权限…

ARMv8-AArch64 的异常处理模型详解之异常向量表vector tables

目录 一&#xff0c;AArch64 异常向量表 二&#xff0c;栈指针以及SP寄存器的选择 三&#xff0c;从异常返回 一&#xff0c;AArch64 异常向量表 异常向量表&#xff08;vector tables&#xff09;是一组存放于普通内存&#xff08;normal memory&#xff09;空间的&#xf…

【机器学习科学库】全md文档笔记:Jupyter Notebook和Matplotlib使用(已分享,附代码)

本系列文章md笔记&#xff08;已分享&#xff09;主要讨论人工智能相关知识。主要内容包括&#xff0c;了解机器学习定义以及应用场景&#xff0c;掌握机器学习基础环境的安装和使用&#xff0c;掌握利用常用的科学计算库对数据进行展示、分析&#xff0c;学会使用jupyter note…

vue从flask获取数据并显示

记录一个前后端分离遇到的问题&#xff0c;即vue前端从flask后端获取数据。具体描述如下&#xff1a;flask只负责连接数据库并获取数据库的数据&#xff0c;并返回给前端vue&#xff1b;vue则需要获取后端返回的数据并显示。 方法如下&#xff0c;分别用一个vue组件和一个flas…

跟着爱学习的饲养员做题记录之两个数之和,力扣1

题目要求在给定的整数数组中找到两个数的索引&#xff0c;使它们的和等于一个特定的目标值。 import java.util.Hashtable;/*** 开发人员&#xff1a; * 时间&#xff1a;2024/2/24*/ //两数之和 public class leecode1 {public static void main(String[] args) {int[] nums …

npm install报错,如何解决

npm install报错可能有多种原因&#xff0c;以下是一些常见的解决方法&#xff1a; 检查网络连接&#xff1a;确保你的网络连接正常&#xff0c;有时候网络不稳定会导致npm install失败。 清除npm缓存&#xff1a;运行命令npm cache clean --force清除npm的缓存&#xff0c;然…

【网站项目】488服装店销售管理系统

&#x1f64a;作者简介&#xff1a;拥有多年开发工作经验&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。&#x1f339;赠送计算机毕业设计600个选题excel文件&#xff0c;帮助大学选题。赠送开题报告模板&#xff…

【CMake】(9) 日志

message 函数被用于向用户显示信息。这个函数可以在 CMake 运行时输出各种级别的消息,包括状态消息、警告、错误等。 message 函数的语法 message([<mode>] "message to display" ...)<mode> 可选的参数,指定消息的类型。可能的值包括: STATUS: 显示…

迷你世界之建筑生成球体

local x0,y0,z00,30,0--起点坐标 local dx,dy,dz60,60,60--外切长方体横纵竖长度 local count,all0,dx*dy*dz--计数&#xff0c;总数 local m,k10000,0--单次生成方块数&#xff0c;无用循环值 local x,y,z0,0,0--当前坐标 local demath.random(2,19)/2 local id600--方块…

评估测试接口软件与网站的使用方法及优劣势比较

评估测试接口软件与网站的使用方法及优劣势比较 导言 在软件开发和测试过程中&#xff0c;对接口进行测试是至关重要的一步。测试接口的软件和网站提供了各种工具和方法&#xff0c;以便开发人员和测试人员能够有效地测试他们的应用程序接口。本文将探讨几种常见的测试接口软…

小米标准模组+MCU 快速上手开发(二)——之模组串口调试

小米标准模组+MCU 开发笔记之固件调试 背景技术名词简介● 小米IoT开发者平台● 小米IoT 模组● 固件● OTA● CRC32固件双串口调试● MHCWB6S-IB 模组资料下载● MHCWB6S-IB 模组管脚图● 上电调试背景 小米标准模组+MCU的开发过程中,由于部分官方资料较为古早,踩了很多的坑…