首页 > 技术文章 > 100层楼扔两个鸡蛋的问题

macyzhang 原文

转载自:http://blog.sina.com.cn/s/blog_6c813dbd0101bh98.html

两个软硬程度一样但未知的鸡蛋,它们有可能都在一楼就摔碎,也可能从一百层楼摔下来没事。

有座100层的建筑,要你用这两个鸡蛋确定哪一层是鸡蛋可以安全落下的最高位置。可以摔碎两个鸡蛋。

 最少需要几次测试,才能得到摔碎鸡蛋的楼层?方案如何?

================================================= 

对于这个问题,如果从编程角度而言,最简单的思路是用动态规划的思想来解决,不过本文不将其从编程角度分析,而是从数学角度对问题进行论述。

 ================================================

对这个问题,

  原始问题——100层楼,最少需要几次测试,才能得到摔碎鸡蛋的楼层】,

直接考虑不容易考虑,但是,如果将这个问题进行一种等价的转换,这个问题将会变得非常容易解答。个人认为,这个转换是解决这个问题的核心,这个转换是:

  转换问题——【两个鸡蛋,进行k次测试,最多可以测试几层楼】

 

如果大家能想到将“原始问题”变为“转换问题”,这个问题个人认为已经解决一半了,转换后,这个问题豁然开朗,思路全开。

 

现在我们以“转换问题”为模板进行考虑,有两个鸡蛋,第一个鸡蛋如果破碎,第二个鸡蛋就必须只能一层一层的测试了,而且,我们要求进行k次测试就将摔碎鸡蛋的楼层必须找到.

=====================================================

考虑第一次测试。第一次测试的时候,第一个鸡蛋不能放置的楼层太高了,否则,如果第一个鸡蛋破碎,第二个鸡蛋可能不能在k次测试后得到结果。但是也不能放置的矮了,因为如果放置的矮了,第一个鸡蛋破碎了还好说,如果没破,我们浪费了一次测试机会,也不能说是完全浪费了,不过至少是让效用没有最大化。所以,第一次测试的时候必须让第一个鸡蛋放置的不高不矮。

 

不高不矮是多高?高到如果第一个鸡蛋破碎后第二个鸡蛋刚好能完成k次测试得到结果这个目标。由此可知,第一次测试所在的楼层高度为k,如果第一次测试第一枚鸡蛋破碎,则剩下k-1层楼,一层一层的试,k次一定能完成目标。

 

如果第一次测试,第一枚鸡蛋没有破碎,则我们现在只有k-1次测试机会了,而且直到了k楼及其以下都是安全的了。我们消耗了一次测试机会,但是一次就测试了k层楼。

 

然后只有k-1次机会了,第二次测试,我们可以在k层的基础上再增加k-1层了,注意,这个时候由于我们只有k-1次机会,所以这次只能再增加k-1层,以保证测试的时候第一枚鸡蛋破碎的情况下仍然能完成任务。

 

于是,重复上述过程,直到最后一次机会,我们总共测试的楼层数为:

      100层楼扔两个鸡蛋的问题

然后,再回到“原始问题”,100层楼,如果需要k次测试才能测试完成,则必须有

100层楼扔两个鸡蛋的问题

则可以得到,k≥14

也就是需要14次测试才能得到结果,而且这个过程也将测试方案一并得出来,就是第一次在14楼测试,如果第一枚蛋碎,则剩余13次机会,13层未知楼层,恰好,第二次在14+13=27楼测试,如此。

如果不是100层,而是N层,需要的测试次数为k,则有

      100层楼扔两个鸡蛋的问题

========================================================= 

然后,这个问题这个时候还可以扩展了,如果我们有三个鸡蛋,有k次机会,我们最大可以测试多少层楼?

思路同前面一样,第一次测试,不能太高也能太矮,必须恰到好处,也就是第一枚鸡蛋如果破碎,剩余k-1次机会能将剩余楼层给测试完。

由上面结论,k-1次机会最多可以测试k(k-1)/2层楼,所以第一次在k(k-1)/2+1层楼,第一次如果第一枚鸡蛋不碎,第二次在此基础上增加(k-1)(k-2)/2+1层楼,于是,三个鸡蛋k次机会总共测试楼层数为

100层楼扔两个鸡蛋的问题

至于四个鸡蛋,五个鸡蛋,以至于M个鸡蛋,可以以此类推,方法同上。此处原理讲通,就不推导了。

=====================================================

题目变形:

链接:https://www.nowcoder.com/questionTerminal/287575fa30804a8b9085ca1747a69b6e
来源:牛客网

由于诺基亚手机不止可以当作手机使用,还可以作为砖头防身,人人的员工小丁想测一测它从多高才能摔破。借助人人公司所在的静安中心大楼(共 27 层),小丁准备从 1 层开始一层一层的将诺基亚手机扔下去,直到摔破为止,显而易见,在最坏的情况下需要扔 27 次才能测出这个临界值(假定顶层的高度一定可以摔破这部诺基亚手机),小丁跟同事小李说了这个想法,小李说他这也有一部同型号的诺基亚手机,正好不用了给了小丁,现在小丁手中有两部诺基亚手机。

( 1 )请你帮忙计算一下在最坏情况下,小丁最少需要扔几次才能测出这个临界值,并且给出具体策略?( PS ,两部手机,第一步手机选择第 k 层扔下去,若是没有摔坏我们可以继续拿来往楼下摔,若是摔坏了,只有一部手机了,还得按照之前一部手机的策略)
( 2 )现在我们发散一下,假设给你 m 部诺基亚手机, n 层的高楼(假定顶层的高度一定可以摔碎),在最坏情况下至少需要扔多少次才能测出临界高度?程序实现,最好给出算法思想,假定输入若干组 m 和 n ,你的程序需要对每组 m 、 n 给出响应结果。(其中 m 属于 [1,50] , n 属于 [1,1000] )
 
 

推荐阅读