题目

2个鸡蛋,100层楼,如何用最少的试验次数得到在鸡蛋落下不碎的最高层数?这一据说曾被谷歌纳入校园招聘题库的经典面试题,想必许多人都曾遇到过,又有多少人与我一样,不加思索就直接回答用二分法查找的?

但是,二分法真的是最优试验方法吗?接下来我们来分析几种解法。

首先我们先认真看一下完整的题目(之前做过这道题的同学可以跳过这一步):

原题:两个软硬程度一样但未知的鸡蛋,它们有可能都在一楼扔下来就摔碎,也有可能从100层楼上扔下来也没事。有座100层的楼,要你用这两个鸡蛋确定哪一层是鸡蛋可以安全落下的最高位置。可以摔碎两个鸡蛋,在最坏情况下,如何用最少的试验次数得到鸡蛋落下不会被摔碎的最高层数?

解法

最笨的方法:遍历查找

把其中的一个鸡蛋,从第1层开始往下扔。如果第一层没碎,换到第2层扔;如果第2层没碎,换到第3层扔…假设第50层没碎,第51层碎了,说明鸡蛋落下不会摔碎的最高层数为第50层。

这个方法在最坏情况下,需要扔99次。

二分法

采用二分查找的方法:

把第一个鸡蛋从一半楼层(50层)扔下。

如果鸡蛋碎了,则第二个鸡蛋就从第1层开始扔,一层一层增长,直到49层。

如果第一枚鸡蛋在50层没有被摔碎,则继续使用二分法,从剩余的楼层的一半(75层)开始往下扔…

在最坏情况下,这种二分法需要进行50次试验0。

平方根法

如何让第一个鸡蛋和第二个鸡蛋的尝试次数尽可能均衡?我们做一个平方根运算,100的平方根为10。

因此我们第一个鸡蛋每10层扔一次,第一次从第10层扔,没碎的话再加10层,即从20层扔…一直扔到100层。

第二个鸡蛋从第一个鸡蛋碎掉的n层往下9层,即n-9层开始一层一层往上试。

这种方法最好的情况为:第一个鸡蛋在第10层碎掉,尝试次数 1 + 9 = 10 次。

最坏的情况为:第一个鸡蛋在第100层碎掉,尝试次数为 10 + 9 = 19 次。

这样子看来平方根的方法算是比较好的方法,那么还有更好的方法吗?

反向思考

我们反向思考一下这个题目:假设题目存在最优解,这个最优解的最坏情况尝试x次,那么我们第一次扔要选择在第几层?

假设第一次扔在x+1层:如果第一个鸡蛋碎了,那么第二个鸡蛋就只能从第1层开始一层一层扔,一直扔到第x层。这样总共尝试了x+1次,与最优解的尝试x次相悖。

假设第一次在x-1层:如果第一个鸡蛋碎了,那么第2个鸡蛋就要从第1层开始扔,一直到x-2层,共尝试了x-2+1=x-1次,虽然没有超出假设次数,但似乎有些过于保守。

假设第一次扔在第x层:

如果第一个鸡蛋碎了,那么第二个鸡蛋只能从第1层开始一层一层扔,一直扔到第x-1层。这样,我们总共尝试了x-1+1 = x次,刚刚好没有超出假设次数。

恰恰是从第x层开始扔,选择高一层或第一层都不合适。

如果第一个鸡蛋没碎,问题就变成了:在100-x层楼往下扔,要求尝试次数不超过x-1次。

那么第二次的尝试次数的上限变为x-1次,所以第2次试验的楼层跨度为x-1层,真实层数为x+x-1层。

以此类推我们可以列出楼层的方程式: x + (x - 1) + (x - 2) + … + 1 = 100

接下来就是求解方程式,我们将这种方法称为解方程法:

解方程法

x + (x - 1) + (x - 2) + … + 1 = 100 => (x + 1) * x / 2 = 100

向上取整得到x=14

即最优解的最坏尝试次数为14次,第1个鸡蛋开始扔的层数也为14层。

第一个鸡蛋没碎的情况下,所尝试的楼层为:14, 27, 39, 50, 60, 69, 77, 84, 90, 95, 99, 100

假设鸡蛋不会被摔碎的最高楼层为55层,那么第一个鸡蛋尝试的楼层为14,27,39,50,60,在第60层碎了;

第二个鸡蛋从51层开始, 51,52,53,54,55,56,第56层碎了,则尝试次数为5 + 6 = 11 < 14

这道面试题的解法到此到一段落,现在你还会认为二分法是这道题的最优解吗?

其实这道题还可以衍生下面的问题:
总共有M层楼,N个鸡蛋,要找到鸡蛋不被摔碎的最高楼层,需要尝试几次?

这个问题就不在这里展开讨论了,大家可以自行尝试求解。

你还在用二分法求2个鸡蛋100层楼的问题吗?相关推荐

  1. 7-5 二分法求多项式单根 (20分)

    二分法求函数根的原理为:如果连续函数f(x)在区间[a,b]的两个端点取值异号,即f(a)f(b)<0,则它在这个区间内至少存在1个根r,即f( r )=0. 二分法的步骤为: 检查区间长度,如 ...

  2. python二分法求解_Python使用二分法求平方根的简单示例

    这篇文章主要为大家详细介绍了Python使用二分法求平方根的简单示例,具有一定的参考价值,可以用来参考一下. 对python这个高级语言感兴趣的小伙伴,下面一起跟随512笔记的小编两巴掌来看看吧! 使 ...

  3. PTA 基础编程题目集 7-18 二分法求多项式单根 C语言

    PTA 基础编程题目集 7-18 二分法求多项式单根 C语言 二分法求函数根的原理为:如果连续函数f(x)在区间[a,b]的两个端点取值异号,即f(a)f(b)<0,则它在这个区间内至少存在1个 ...

  4. 用C语言解“二分法求多项式单根”题

    7-18 二分法求多项式单根 二分法求函数根的原理为:如果连续函数f(x)在区间[a,b]的两个端点取值异号,即f(a)f(b)<0,则它在这个区间内至少存在1个根r,即f®=0. 二分法的步骤 ...

  5. 用Python解“二分法求多项式单根 ”题

    7-18 二分法求多项式单根 二分法求函数根的原理为:如果连续函数f(x)在区间[a,b]的两个端点取值异号,即f(a)f(b)<0,则它在这个区间内至少存在1个根r,即f®=0. 二分法的步骤 ...

  6. matlab 二分法求方程近似解

    二分法求方程近似解 %用二分法求方程x^2-2=0近似解 function result=approximate_solution(d,a,b) %精度值d,初始值a,b f=@(x)x^2-2;%匿 ...

  7. note 5 二分法求平方根,素数,回文数

    +二分法求平方根 x = float(raw_input('Enter the number')) low = 0 high = x guess = (low + high ) / 2 if x &l ...

  8. 信息学奥赛一本通(1241:二分法求函数的零点)

    1241:二分法求函数的零点 时间限制: 1000 ms         内存限制: 65536 KB 提交数: 5682     通过数: 3407 [题目描述] 有函数:f(x)=x^5−15x^ ...

  9. 二分法求函数的零点(信息学奥赛一本通-T1241)

    [题目描述] 有函数:f(x)=x^5−15x^4+85x^3−225x^2+274^x−121 已知f(1.5)>0 ,f(2.4)<0 且方程f(x)=0 在区间[1.5,2.4] 有 ...

最新文章

  1. 基于路由器网络诊断步骤和故障排除技巧
  2. 成功解决gensim\matutils.py:737: FutureWarning: Conversion of the second argument of issubdtype from `int
  3. HTML5 Canvas中处理图像和视频
  4. uploadify没反应
  5. CGI、FastCGI和php-fpm的概念和区别
  6. 如何在yml中加上git用户名和密码的验证_使用Apollo升级一下yml文件管理和发布
  7. 为何python不好找工作-为何python不好找工作,seo行业不好转行了
  8. SAP 是不是很烂的一个ERP软件
  9. arma 预测 matlab代码,求助:ARMA模型进行预测
  10. 利用datafaker批量生成测试数据
  11. MODBUS通讯协议内容讲解
  12. java文字淡入淡出显示特效,jQuery超酷文字淡入淡出显示特效
  13. 【广告类型】富媒体 Rich Media Ad 介绍
  14. Cocoa-专业术语
  15. 读到良葛格的反思Hello World
  16. 华科计算机系教学大纲,《批判性思维》课程教学大纲
  17. 补充:混淆矩阵、图像分割指标计算
  18. JavaScript基础知识笔记
  19. 程序员,被代码耽误的段子手
  20. QQ找茬辅助工具的制作

热门文章

  1. 江苏发展大会上有哪些科技界大佬,他们的“隐私”你知道多少?
  2. 智慧停车服务器及存储系统设计,浅谈:停车场管理系统系统组成
  3. 论文阅读笔记《Few-Shot Learning with Global Class Representations》
  4. 微信小程序随机生成文案
  5. seo和sem有什么关系
  6. 服务器被攻击了怎么办?海外服务器有什么有特点?网址或者APP被攻击了怎么办?
  7. opencv怎么找到手指最高处
  8. java tessdata训练_Tesseract训练中文字体识别
  9. 关于幼儿教师音乐素养对幼儿成长影响力的研究的论文怎么写呀
  10. 关于0x3f3f3f3f(0x四个3f)