称球问题的通用解法
来源:互联网 发布:网站关键词优化查询 编辑:程序博客网 时间:2024/04/29 11:40
最近看了个算法题 据说还是google面试题之一,大意是:八个球已知其中有一个是偏重的,问最少几次称出来? 之前我在网上还有个更难的,大意是:13个球已知其中有一个重量异常(重或者轻),给一个天平3次称出那个异常球。 仔细想想 其实这两个题目是有紧密联系的。13球问题的解答需要用到8球问题的解法。 先看看 8球与13球问题的解法: 8球: 先将球8个球分成3堆:3,3,2的形式(3,3是代表在天平两端的球数)。 1、称一次找出重的一边(平衡就只要再称剩下两个中重的一个即可,2次搞定); 2、重的一边三个球,取出两个称:如果平衡则是另一个,不平衡就是重的那个(2次搞定)。 所以,8个球出重的一个球需要两次。 13球: 把球分成三堆:4,4,5的形式。(5,5,3的分法需要4次)。 1、平衡将5个球分成两堆(2,3); 1.1、将分好的三个球替换天平上任意一端得三个球; 1.2、查看天平状态,如果发生偏移则说明异常球就在这三个中,而且可以知道是轻还是重;如果没有发生偏移则说明在另外两个球中; 1.2.1、如果在三个球中间,且知道轻重,则任意取两个球再称一次就能找出异常球; 1.2.2、如果在两个球中不知道轻重,则取正常球一个,再在两个球中任意取一个称;如果平衡则是两个球中的另一个;如果不平衡则是除去正常球以外的另一个; 平衡的情况只要称三次。 2、不平衡则在5个正常球中取三个与天平上重的一侧(轻的一侧也行)的4个球中的3个交换 ;然后将重的一侧4个球中没有交换的一个球与轻的一侧的4个球中任意一个互换;再称; 这个时候可能出现3种状态:(注意重的一侧的球全部发生了交换!) 2.1、天平保持不变:则说明异常球在天平轻的一侧的没有被交换的3个球之中;这样就再称1次便可找出异常球; 2.2、天平平衡:则说明异常球在换下天平的三个球中;而且是重球,这样再称1次就能解决; 2.3、天平发生倾覆:则说明异常球在左右互换的两个球中,而且不知道异常球的轻重;这个时候可以取两个球中的一个与一个正常球称;如果平衡则是两个球中的另一个球;如果不平衡则是正常球以外的另一个。 所以可以看出两种情况都最多只要3次就能搞定。 那么有什么联系吗? 1、称13个中异常的时候在第一次称不平衡的条件下,互换的过称实际上是将球的轻重做了区分(因为天平两边的交换其实只铁定只要再称一次便可);将异常球的轻重得出来而且锁定了范围。这时,问题就退化为“8球问题”了; 2、如果天平平衡,则异常球肯定在天平下的剩余的球。这个时候将剩下的球分半,一半与天平上的正常球交换,一半不动。其实是一种变形的“13球”问题。因为,分半以后跟交换以后的正常球正好变异成一个球数为(N/2上取整+1)个球的新“13”球问题的称完一次时的情况。(将分开的球看做天平两边不平衡的两端,交换下来的球看着做天平下的正常球!) 而且肯定称的次数会比(N/2上取整+1)少1次,所以这样一来这种情况的称数是:1+(Recusive F(N/2上取整+1)个球的次数-1)次=F(N/2上取整+1)-F(N)为计算13球问题的函数。根据常识,F(N)>=F(N/2上取整+1)。所以其实这种情况是可以不考虑的! 综合1,2可以看出,13球问题其实是分组处理以后的8球问题。 这一来可以得出解N个球中称出一个异常球的通用解法: 将N个球分成3堆,保证形成M,M,M或者M+1,M+1,M或者M,M,M+1的分法(肯定是可以的,因为任何数除3余数只能是0,1,2,对应上面三种情况。因为这样能保证重的那边或者轻的那边的球都被交换掉!)。 令解“8球”问题的函数为F(X);则解N球1个异常球的方法是G(x)=2+F(M)。F(X)是一个递归函数,每一步都是贪心的。(加2表示做F()之前其实已经称了2次了)
这样一来G(x)=2+F(M)很简单的形式,解决了复杂的问题。
- 称球问题的通用解法
- 称球问题的测试解法
- 称球问题的测试解法
- 称球问题的测试解法
- 称球问题的测试解法
- 称球问题的测试解法
- 称球问题的测试解法
- 称球问题的测试解法
- 称球问题的测试解法
- 称球问题的测试解法
- 称球问题的测试解法
- 称球问题的测试解法
- 称球问题的测试解法
- 称球问题的测试解法
- 称球问题的测试解法
- 称球问题的一般解法
- 由信息论的熵引出称球问题问题的一般解法
- 一种通用的SingleNumber问题解法
- 围棋入门
- Ubuntu9.10下-星际译王及其辞典安装
- More Joel On Software中文版小编随想之一
- 09.11.12学习日记
- mysql数据同步
- 称球问题的通用解法
- ORACLE中in 和 exists区别
- 我的CNBLOG http://www.cnblogs.com/pengyq/
- Java的反射机制
- 禁止VMware发出的BEEP声音
- Valgrind 使用简单说明
- 图解:如何在VM中安装Linux系统。
- 怎么回事?
- Notepad 获取与修改文本内容。