二分法

有一栋100层高的大楼,给你两个完全相同的玻璃球。假设从某一层开始,丢下玻璃球会摔碎。那么怎么利用手中的两个球,用什么最优策略知道这个临界的层是第几层?

半世苍凉 提交于 2020-01-07 20:13:39
题目有一栋100层高的大楼,给你两个完全相同的玻璃球。假设从某一层开始,丢下玻璃球会摔碎。那么怎么利用手中的两个球,用什么最优策略知道这个临界的层是第几层???  每次肯定是由低的楼层往高的楼层尝试,直到在楼层f(k),第一个球已经碎掉了,记录上一个尝试的楼层为f(k-1),在此楼层,玻璃球不会碎,所以接下来要尝试 f(k-1)+1,f(k-1)+2,f(k-3)+3, ....,知道有一个楼层碎了,这个楼层就是解啦,最坏的是到达f(k)-1 层。   接下来的解决方案就很容易想出了:既然第一步(确定临界段)的投掷数增加不可避免,我们就让第二步(确定临界层)的投掷数随着第一步的次数增加而减少。第一步的投掷数是一次一次增加的,那就让第二步的投掷数一次一次减少。假设第一次投掷的层数是f,转化成数学模型,f+(f-1)+...+2+1就表示从f开始猜,每次的增量都比前一次的曾量减1的情况下,最后猜的那个数(即 f+(f-1)+...+2+1 ),按照提议要求f+(f-1)+...+2+1>=99,即f(f+1)/2>=99(第一次测试点选择100层是无意义的,必然会碎,所以无任何测试价值,所以第一次测试点k是1-99中的一个数),解出结果等于14。丢下第一颗鸡蛋的楼层就分别是 14 , 27 , 39 , 50 , 60 , 69 , 77 ,84 , 90 , 95 , 99 。

二分法的应用

梦想的初衷 提交于 2020-01-07 19:31:40
今天学到的新知识集合 1.bool函数可以直接对变量进行操作而且返回值为0.1; 如下面这个代码就可以看到没有输入a[i]的形参但是仍然可以对其进行操作 return 后面的语句为真就返回1 否则返回0 所以用于if(judge(k))判断是可以的 bool judge(const int &len) // 用于判断的 子函数 { long long cnt=0; //部分情况可能爆int for (int i=0;i<n;i++) cnt+= (long long)(a[i]/len); return cnt>=k; } 2.关于二分法 二分法的最简单形式就是区间的取换 目前我觉得难点在于判断条件 今天做了几道二分题 感觉自己是个菜鸡 第一题就是练手的模板题 用于弄清楚二分法的概念 #include <iostream> #include<bits/stdc++.h> using namespace std; int n,x,i,mid,t,w; const int N=2000005; int a[N]; int main() { while(~scanf("%d %d",&n,&x)) { for(i=0;i<n;i++) scanf("%d",&a[i]); sort(a,a+n); t=0;w=n-1; while(t<=w) { mid=(t+w)/2; if(a

【二分法】2.34. 在排序数组中查找元素的第一个和最后一个位置

心已入冬 提交于 2020-01-01 17:24:12
给定一个按照升序排列的整数数组 nums,和一个目标值 target。找出给定目标值在数组中的开始位置和结束位置。 你的算法时间复杂度必须是 O(log n) 级别。 如果数组中不存在目标值,返回 [-1, -1]。 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: [3,4] 示例 2: 输入: nums = [5,7,7,8,8,10], target = 6 输出: [-1,-1] 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/find-first-and-last-position-of-element-in-sorted-array 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 来源: CSDN 作者: 海绵大叔 链接: https://blog.csdn.net/weixin_42655231/article/details/103793213

list、冒泡、二分法

淺唱寂寞╮ 提交于 2019-12-31 22:09:15
1.遍历第一次,寻找最大值,并且记录最大值的索引max_index 2.list(dict,str) 伪代码: if(是不是有饭吃): 如果是真 执行 (缩进) else: 如果是假 执行 写代码学习过程 1.用草稿纸画一下思路 2.把草稿纸上的内容,写成伪代码 3.伪代码翻译成代码 list list是有顺序的 表示方法: [] dict dict没有顺序 { 'name':'reboot' } list的特点: 有序 通过索引获取值:列表[索引] 两个Python内置函数: len(列表) 返回列表的长度 max() 最大值 min() 最小值 关于变量名: 不可以是list,len,max,min,del 删除列表元素: del删除元素(根据索引) list: 获取,删除,修改(直接赋值) 冒泡排序: 冒泡排序是一种典型的通过交换元素消除逆序的排序方法,是一种最简单的方法。 思路: (1) 每一遍检查将一个最大的元素交换到最后的位置,一些较大元素向右移动,前一个for循环控制第一层元素,从0到7,即range(len(lst)),第二个for循环从1到range(1,len(lst)-i)遍历。 (2)从左到右比较相邻元素,前一个元素较小就交换。 (3)如果原始待排序序列本身有序,可以提前退出排序,设置flag标志,为 true时,退出循环。 例: 两种思路实现冒泡算法:

内置函数, 递归, 二分法

て烟熏妆下的殇ゞ 提交于 2019-12-25 00:54:22
一. lambda() a = lambda n: n ** 2 a = lambda x, y: (x, y) a = lambda x, y: x, y 这个需要两个变量名来接收, 把y赋值给第二个变量名 fn = lambda *args: max(args) lambda有返回值 二. sorted() sorted(iterable, key, reverse) lst = sorted(lis, key = lambda el: el[:2], reverse = True) lst = sorted(lis, key = func, reverse = True) func不加括号 sorted函数会把lis的每一个元素交给key, 然后计算出这个元素的权重, 整个函数按权重进行排序, sorted有返回值 三. filter() filter(function, iteraable) f = filter(lambda el: int(el[0]) < 5, lst) print(list(f)) filter函数返回True的都会保留, False都会去除 获取的返回值是一个迭代器 m = map(func1, map(func2, map(func3, lst))) # 分而治之 m = map(lambda x, y, z: x + y + z, [1,2,3

php常用的排序算法与二分法查找

徘徊边缘 提交于 2019-12-22 06:40:50
一 : 归并排序 将两个的有序数列合并成一个有序数列,我们称之为" 归并 "。 归并排序(Merge Sort)就是利用归并思想对数列进行排序。根据具体的实现,归并排序包括" 从上往下 "和" 从下往上 "2种方式。 1. 从下往上的归并排序 :将待排序的数列分成若干个长度为1的子数列,然后将这些数列两两合并;得到若干个长度为2的有序数列,再将这些数列两两合并;得到若干个长度为4的有序数列,再将它们两两合并;直接合并成一个数列为止。这样就得到了我们想要的排序结果 2. 从上往下的归并排序 :它与"从下往上"在排序上是反方向的。它基本包括3步: ① 分解 -- 将当前区间一分为二,即求分裂点 mid = (low + high)/2; ② 求解 -- 递归地对两个子区间a[low...mid] 和 a[mid+1...high]进行归并排序。递归的终结条件是子区间长度为1。 ③ 合并 -- 将已排序的两个子区间a[low...mid]和 a[mid+1...high]归并为一个有序的区间a[low...high]。 /** * 归并排序实现过程 * @param Array $arr 待排序的区间数组 * @param Int $start 第一个区间数组的起始位置 * @param Int $mid 第一个区间数组的结束位置,第二个区间数组的起始位置 * @param Int

C++ 一个简单的二分法查找

限于喜欢 提交于 2019-12-21 05:16:17
#include <iostream> #include <vector> using namespace std; int findBin(vector<int>& arr,int target){ int l=0,r=arr.size()-1; int mid; while(l<=r){ mid=(l+r)/2; if(arr[mid]==target) return mid; if(target<arr[mid]){ r=mid-1; } else{ l=mid+1; } } return -1; } int main() { int arr[]={1,2,4,5,7,8,10,12,13,18,24,29,54,321,777,785,988}; vector<int> arra(arr,arr+17); int num; while(1){ cin>>num; if(num==-1)return 0; cout<<findBin(arra,num)<<endl; } } 来源: CSDN 作者: 啊罗罗 链接: https://blog.csdn.net/dyyzlzc/article/details/103606148

查找-二分法查找(折半查找法)

£可爱£侵袭症+ 提交于 2019-12-18 08:47:14
实现查找指定数值在 元素有序的数组 中存储的位置(索引),返回该位置(索引)。 解题步骤: 1.定义3个用来记录索引值的变量,变量min记录当前范围最小索引值,初始值为0;变量max记录当前范围最大索引值,初始值为数组长度-1;变量mid记录当前当前范围最中间元素的索引值,初始值为(min+max) / 2 2.使用循环,判断当前范围下,最中间元素值与指定查找的数值是否相等 若相等,结束循环,返回当前范围最中间元素的索引值mid 若不相等,根据比较结果,缩小查询范围为上一次查询范围的一般 中间元素值 比 要查询的数值大,说明要查询的数值在当前范围的最小索引位置与中间索引位置之间,此时,更新查询范围为: 范围最大索引值 = 上一次中间索引位置 -1; 中间元素值 比 要查询的数值小,说明要查询的数值在当前范围的最大索引位置与中间索引位置之间,此时,更新查询范围为: 范围最小索引值 = 上一次中间索引位置 +1; 在新的查询范围中,更新中间元素值的位置,再次使用最中间元素值与指定查找的数值是否相等。 中间索引值 = (范围最小索引值 +范围最大索引值) / 2; 3.每次查询范围缩小一半后,使用if语句判断,查询范围是否小于0个元素,若小于0个元素,则说明指定数值没有查询到,返回索引值-1。 //二分查找法(折半查找法) public static int halfSearch(int

2019.12.07 二分法查找二维数组

扶醉桌前 提交于 2019-12-07 09:15:41
/** * BinarySearch.java * com.oracle.array * * Function: TODO * * ver date author * ────────────────────────────────── * 2019年12月5日 17671 * * Copyright (c) 2019, TNT All Rights Reserved. */ package com.oracle.array; /** * ClassName:BinarySearch * Function: TODO ADD FUNCTION * Reason: TODO ADD REASON * * @author 17671 * @version * @since Ver 1.1 * @Date 2019年12月5日 下午8:51:26 * * @see */ public class BinarySearch { public static String[][] news= {{"京东物流","100"},{"家乐福","400"}, {"百度搜索","600"},{"4399小游戏","1000"}}; public static void main(String[] args) { binarySearch(600); } public static void

排序算法:二分法插入排序

ε祈祈猫儿з 提交于 2019-12-06 22:27:45
二分法插入排序: 在上一篇文章 排序算法:插入排序 中,介绍了插入排序。其中,插入排序的“插入”二字体现于在寻找有序区间[R0,Ri-1]内第一个比Ri小的Rx,然后将Ri插入Rx之后,如果Ri>Ri-1,那正好,Ri不需要再与有序区间的其他元素比较。 二分法插入排序沿用了插入排序的思路,而且由于[R0,Ri-1]是有序序列,在寻找Ri的插入位置时,可以采用二分查找法搜索有序区间中比第一个Ri小的元素,这样就减少了比较次数,提高了插入排序算法的性能。 以长度为6的序列 {6,3,5,4,1,2} 的二分法插入排序过程做示范: 第一趟排序:[3 6] 5 4 1 2 (3插入6之前) 第二趟排序:[3 5 6] 4 1 2 (5插入6之前) 第三趟排序:[3 4 5 6] 1 2 (4插入5之前) 第四趟排序:[1 3 4 5 6] 2 (1插入3之前) 第五趟排序:[1 2 3 4 5 6] (2插入3之前) (注:用中括号括起来的是有序区间,之后的元素序列为待排区间) 可以看见二分法插入的排序过程和插入排序的过程是一摸一样的,但是其中寻找插入位置的过程是不一样的。 用第5趟排序过程作详细介绍第5趟排序过程需要寻找R5,即2的插入位置: 第五趟排序前的序列:[1 3 4 5 6] 2 首先,定义右边界right为R4,值为6,左边界为R0,值为1。[R0,R4]的中间元素为R(4