二分答案
这是一个对二分答案的总结
首先明确的概念是:二分查找虽然是在中点处截取,但是随着截取的越来越精细,是可以确定把答案落在一个具体值身上的
根据二分查找的这个特性,可以快速的在可枚举的数据中进行定位
使用二分答案的条件:
1.可枚举
2.序列呈现递增的形态(这也契合二分查找的要求)
3.
下面上例子!
18725 宇宙迁跃
时间限制:1000MS 代码长度限制:10KB
提交次数:0 通过次数:0题型: 编程题 语言: 不限定
Description
在基地的科学家发明“透镜”之后,宇宙航行变得更加效率。 作为基地元首的的代理人,你需要在K天内乘坐飞船到达首都川陀。 飞船可以花费一天时间,通过迁跃从一个星系到达另一个星系,但绝不能迁跃到星系之间,那样不但会遇到一些自然危险,也可能永远迷失。 我们把基地至川陀间星系的坐标看成是一个线性序列,例如a星系坐标是10,b星系坐标是15,那么飞船必须具备不小于5的迁跃能力才能从a航行至b。 基地坐标为0,请你根据基地至川陀间的N个星系坐标,计算飞船的迁跃能力至少为多大,才能在K天内(包含K天)到达川陀。
输入格式
第一行两个整数N和K。(1=<N<=10000,1=<K<=10000) 第二行N个整数,表示N个星系的坐标ai,题目确保坐标由小到大排列。(0=<ai<=100000)
输出格式
仅一行,飞船的最小迁跃能力。
输入样例
5 2 1 4 6 10 19
输出样例
10
提示
样例说明:川陀的坐标为最后一个值19。 飞船的迁跃能力至少为10,才能在2天内到达川陀。
对这个例子的分析:
用常规思路来思考:从1开始枚举,每个节点,每个都试探能不能成功飞行,这是OK,而且枚举的过程也是从1开始不断增大的
所以我们在main函数里面 通过二分查找在茫茫的范围内通过二分查找来定位最终的答案
ps:总有一个最终的答案ans这是一个临界值,比这个答案小一点的,飞船飞不过去,比这个答案大一点的,飞船都可以飞的过去,所以称之为至少!
main函数里面是常规的二分模板 check 函数是判断是对mid的判断
如何构造check来进行判断???
check(int mid) //由于要判断,满足的条件有两个:1.飞船可以成功跃迁(如果都跳不过去,那换一个更大的试一下,所以反馈回去,应该是定位到折半查找的左半段)
2.天数不会超过要求的值(这里要求至少,那肯定是把给定的天数都用掉,才可能尽可能的小),这个用一个计数器
{
跃迁判定:1.相邻点都跳不过去,太菜了,还是找一个更大的吧,直接return 0;
2.相邻点可以跳过去,那就一直i++,直到在某个点卡住了(那还是可以找落脚点的,大不了一个个格子跳)
由于是用for来进行循环的,能够走到这一步,说明上一个点是可以跳过去的,就如下图所示,此时要做两件事情
①把a[i-1]设置为落脚点,更新落脚点的位置pre=a[i-1]
②记录跳跃次数 c++;
!!!!!!!!!!这里有一个非常非常非常容易错的地方,跳跃次数的更新,是当某个点被卡住的时候才会更新,试想一下,现在的跳跃能力超级无敌强,那检测到最后一个格子,他都不会被卡住,那记录的跳跃次数将为0,也就是说,当跳跃能力很强的时候,最后一个点是不会被记录的,所以要人为的在检测的最后,把跳跃次数加一次(最后一跳)
}
上代码
#include<iostream> using namespace std; int a[10005],n,k; int check(int x) { int i=1,c=0,pre=0; while(i<=n&&c<=k) { if(x<a[i]-a[i-1])return 0;//如果都不支持相邻点之间的条约,那么不用再考虑 if(a[i]-pre>x)//如果现在到这个点跳不过去了,那就跳到前一个点(因为是逐个循环,前一个点肯定可以到),那么从这轮开始pre就是a[i-1] { pre=a[i-1]; c++;//记录跳跃的次数,需要多跳一次了 } else i++; } c++; //前面测试了可行性,但是不会记录最后一跳,补最后一天!! return c<=k; } int main() { ios::sync_with_stdio(0),cin.tie(0); int i,j,k; cin>>n>>k;//记录站点的数量 天数 for(i=1;i<=n;i++) //读入数据 cin>>a[i]; int l=1,r=1000000,mid,ans; while(l<=r) { mid=(l+r)/2;//这是二进制位往左移动一格,意思就是/2 if(check(mid)) { ans=mid; r=mid-1; } else l=mid+1; } //在这个部分采用二分搜索的方法,在茫茫的数字中寻找那个临界点 cout<<ans; return 0; }
原文地址:https://www.cnblogs.com/wengst/p/12993500.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PHP入门之类型与运算符
- 栈论 : 递归与栈式访问,如何用栈实现所有递归操作(幼儿园题目篇,题目3)
- Maven是什么? Maven的概念+作用+仓库的介绍+常用命令
- JDK8;HashMap:再散列解决hash冲突 ,源码分析和分析思路
- 写一个 Singleton
- 树莓派基础实验31:MPU6050陀螺仪加速度传感器实验
- springboot gradle mybatis mysql配置(注解)
- PHP入门之流程控制
- 常用进制转换方法(取商留余)原理解析, 附基于栈实现进制转换的代码
- 用 jdom 解析 xml 文件时如何解决中文问题?如何解析?
- PHP入门之函数
- spring boot 启动报错 org/springframework/core/ErrorCoded
- PHP入门之数组
- PHP基础之排序
- 关于mysql limit offset的一点优化