经典面试问题:12小球问题算法(抄的)

来源:互联网 发布:linux html中文乱码 编辑:程序博客网 时间:2024/05/29 04:46

IQ:

 

12 颗玻璃球大小一样, 不知道哪一颗重了, 还是轻了. 请用天平秤秤3, 把其中的一颗重量不均匀的玻璃球取出来!

 

高手的给的答案

先把小球平均分成三组每组4个。

1)第一次把其中两组放到天平两边,若平衡,这种情况较简单,这里不说了,

2)若不平衡,假定轻的是左边的四个小球,编号为1234号;重的是右边,编号为5678,第三组(没放在天平的)编号为912

3)第二次把1259放在天平左边,34610放右边若平衡,则不同的小球是78,而且比一般球重,第三次容易区分。

4)若天平还是左轻右重, 则不同的小球是126之一,第三次也容易区分,只需把12秤出轻的便是,否则是6,若天平变为左重右轻,则不同的小球为345之一,方法与上同。

 

 

高手的给的答案

先把小球平均分成三组每组4个。

1)第一次把其中两组放到天平两边,若平衡,这种情况较简单,这里不说了,

2)若不平衡,假定轻的是左边的四个小球,编号为1234号;重的是右边,编号为5678,第三组(没放在天平的)编号为912

3)第二次把1259放在天平左边,34610放右边若平衡,则不同的小球是78,而且比一般球重,第三次容易区分。

4)若天平还是左轻右重, 则不同的小球是126之一,第三次也容易区分,只需把12秤出轻的便是,否则是6,若天平变为左重右轻,则不同的小球为345之一,方法与上同。

 

 

正解。不过此题答案不唯一。大家可以继续想。

核心思路是,每次称重,不管天平平衡与否,都能尽可能多的排除掉一些可能。

和海盗问题一样,这也是MS前几年的面试题之一

 

 

 

 

太容易了 分成三组!

A{a0,a1,a2,a3}

B{b0,b1,b2,b3}

C{c0,c1,c2,c3}

if(A==B)

{

   D' = {c0,c1,c2}

        if ( D' = = {a0,a1,a2} ) {

                c3 is bad ball;

         } else if( D' > {a0,a1,a2} ){                

                 D" = {c0 ,a0};

                 D"" = {c1,a1};

                  if( D" = = D"" ){

                    c2 is bad ball;

                  }else{

                        if( D" > D"" )

                           c0 is bad ball;

                        else

                           c1 is bad ball;

                 }

        }else if( D' < {a0,a1,a2}) {

        D" = {c0 ,a0};

            D"" = {c1,a1};

            if( D" = = D"" ){

               c2 is bad ball;

            }else{

                if( D" > D"" )

                 c1 is bad ball;

           else

                 c0 is bad ball;

        }

}

 

if(A > B){

D' = {a0,a1,b2,c3};                  ‘选球过程中还有a3,b3,b1没有选

D" = {b0,c1,a2,c0};

if( D' == D" ){             

     {a3,b3}{c0,c1}比较

     if( > )

           a3 is bad ball

     if( < )

           b3 is bad ball

     if( = )

           b1 is bad ball           

}

 

if(D > D" ){        ‘假设坏球大,那么就在a0,a1当中;假设坏球小,那么就在b0

   坏球在a0,b0,a1之间

   {a0,b0}{c0,c1}比较

   ... if( > )

           a0 is bad ball

     if( < )

           b0 is bad ball

     if( = )

           a1 is bad ball 

 

}

if(D'< D" ){

a2,b2任一,和标准c0比较   ‘假设坏球大,那么就在a2当中;假设坏球小,那么就在b2

     if a2>c0

a2 is bad ball 

else

b2 is bad ball

}

}

 

 

if(A < B){

D' = {a0,a1,b2,c3};                  ‘选球过程中还有a3,b3,b1没有选

D" = {b0,c1,a2,c0};

if( D' == D" ){             

     {a3,b3}{c0,c1}比较

     if( > )

           b3 is bad ball

     if( < )

           a3 is bad ball

     if( = )

           b1 is bad ball            

}

 

if(D < D" ){        ‘假设坏球小,那么就在a0,a1当中;假设坏球大,那么就在b0

   坏球在a0,b0,a1之间

   {a0,b0}{c0,c1}比较

   ... if( > )

           b0 is bad ball

     if( < )

           a0 is bad ball

     if( = )

           a1 is bad ball 

 

}

if(D'> D" ){

a2,b2任一,和标准c0比较   ‘假设坏球大,那么就在b2当中;假设坏球小,那么就在a2

     if a2>c0

b2 is bad ball 

else

a2 is bad ball

}

}

 

 

这题我两年关就做过了.我来回答.开始同ziqing_1_2_3一样

 

 

先把小球平均分成三组每组4个。

 分别是  组一, A.B.C.D

         组二, 1.2.3.4 

         组三, a.b.c.d

 先用第一组和第二组称.平衡就不用说了(重或轻的球在组三中).

先假设.组一重.组二轻.

 第一组和第二组不平衡.说明组一和组二中有一个球或重或轻.

 再用A.B.1 C.D.2去称(这后面就要用逻辑去想了) 平衡那是在3.4球不同.

 不平衡.

 1.平衡有没有出现交换.那么 A.B 中有一球重. 2

 2.平衡发生交换那么 C.D. 中有一球重. 1

再用A.2C.1a.b.就可以推理出不同重量的球

 

 

3个以下   三的一次方   1算出  1V1

9个以下   三的二次方   2算出  3V3   1v1

27个以下  三的三次方   3算出  9V9   3V3  1v1

81个以下  三的四次方   4算出  27v27 9V9   3V3  1v1

.....

以下类推..

 

12个的合理算法,分为9,3,0

9中的话,2次可算出  (9再分3,3,3 )

3中的话,1次可算出

 

12个最多三次可算出结果

以上所有对半分的答案肯定不是最合理的,些题考的只是一个算法,12只是一个特例,有没有考虑过:27,24,81....20003333个的情况呢...

 

3的次方是此题的规律...

 

 

 

 

经典面试问题:12小球问题算法

作者:成晓旭

1   问题描述:

现有12个外形相同的小球,只有其中一个小球质量不同(不能确定较重还是较轻),请用天平找出是哪个小球不同,而且还要找出究竟是轻是重?条件:只能称三次。

此问题已经在网上广为流传,相信很多朋友早有自己的解答方法。本人在2002年底听到此问题,煞费心思终到此解,之后,向我了解问题解决方法及过程的朋友络绎不绝;所以索性做了个软件工具来演示自己的解答思路和过程。

温馨提示:4年前的程序写得很垃圾,用Java重新实现的版本已在计划之中,敬请继续关注我的Blog

2   软件设计

其实,这类软件没有什么设计可言,本质就是一个核心算法的实现。所以,这里的设计,只是我从Rose中逆向工程后生成的文档组织而成。

其实,这个程序中含有大量的OPP的痕迹,也没有真正看到设计模式的应用;偶尔回头看看自己4年前写的代码,再回想起自己当初完成此程序的“莫大成就感”!真是幼稚之极!

2.1、包设计

程序共设计为3个包:

Common包:小球问题的算法封装,里面采用面向过程的实现方式,没有任何类。主要对外提供的方法有:

//清除画面方法

    procedure ClearCanvas(aCanvas: TCanvas; aRect: TRect);

    //小球问题条件设置方法

    procedure Draw_Ball_Config(

        AllBall:array of TC_Ball;

        ACanvas:TCanvas;

        aClearRect: TRect;

        bShowTrace:Boolean);

    //小球问题解决方法

    procedure Serach_Error_Ball(

        AllBall:array of TC_Ball;

        ACanvas:TCanvas;

        aClearRect: TRect;

        bShowTrace:Boolean);

BallType包:小球问题演示程序的显示绘制封装,主要包括与显示绘制相关的结构和类,以及一些过程和函数。

BMani包:小球问题的界面显示类,演示界面的控制、业务方法的调用、处理结果的呈现。

2.2、主要类简介

BallType包中的界面绘制:

TC_Ball//小球问题:小球抽象数据类型

TC_SearchBall//小球问题:被寻找的目标小球抽象数据类型

TC_CmpPara//小球问题:一次比较的参数的抽象数据类型

TC_Ball_Class//小球问题:小球抽象类

TC_Balance//小球问题:天平抽象类

TC_Compare//小球问题:天平比较一次抽象类[行为抽象]

TC_Ball_Problem//小球问题抽象类<2003-11-14至今未被使用,是为方法的通用性而设计>

核心的业务类关联视图:其实从这张乱如蛛网的依赖关系图中,足以说明设计之丑陋了。

 

 
原创粉丝点击