代码改变世界

称球问题

2007-10-21 11:32  老博客哈  阅读(2419)  评论(4编辑  收藏  举报

称球问题的一个经典形式如下:

"有十二个外表相同的球,其中有一个坏球,它的重量和其他十一个有轻微的(但是可以测量出来的)差别。现在有一架没有砝码的很灵敏的天平,问如何称三次就能保证找出那个坏球,并知道它比标准重还是轻。"

这个问题比较好的叙述和解答可以参加《称球问题--经典智力题推而广之三》和 WC2003 何林的论文《一类称球问题的解法》(用到了三分及判定树的思想)。

详细的过程我就不写了,把加个结论再叙述一下:

有一架天平,有n(n >= 3)个球,其中一个是次品。(注:下面用符号{}表示取上整,[]表示取下整)

结论1 次品的重量比其他重(轻),称{log3(n)}次就能找出那个次品

结论2  次品的重量不知。有一个标准球。称{log3(2*n)}次可以找出那个次品,并且知道次品的轻重。

结论3  次品的重量不知。称{log3(2*n+2)}次就能找到次品,并且知道次品的轻重。

结论4  次品的重量不知。有一个标准球。称{log3(2*n-1)}次可以找出次品。

如果m>=0,n>=0且m,n不同时为0.在编号从1到m+n的m+n个球中,我们知道1到m号球要么是标准球,要么比标准球重,而m+1到m+n号球要么是标准球,要么比标准球轻,此外我们还知道有一个坏球(但不知轻重)

结论5  要保证m+n个球中找出坏球并知道其轻重,至少需要称{log3(m+n)}次。 如果m和n不同时为1,那么称{log3(m+n)}次就足够了。如果m=n=1,并且另有一标准球,那么称{log3(m+n)}={log3(1+1)} = 1次就足够了。注:如果m=n=1并且没有标准球,那么永远也称不出坏球。

现有n个小球,其中有一个坏球不知道比标准球轻还是重,令H={log3(2*n)}。要保证N个球中找出坏球并知道轻重,至少需要称H次。假设n不等于2,则有

结论6 如果N<(3^H - 1)/2,那么称H次就足够了;N=(3^H - 1)/2,那么称H次足以找到坏球,但不足以知道坏球比标准球是重还是轻;如果N=(3^H - 1)/2,而且还另有一个标准球,那么称H次足以保证找到坏球和知道坏球比标准球轻还是重。特别地,当N=2时,如果还另有一个标准球,称H={log3(2*2)}=2次足以保证找到坏球和知道坏球比标准球轻还是重。

下面是几个和“称球问题”相关的题目:

1. hit 2519 Fake coin

上述结论1

2. ustc 624 称球问题

这个题目是给定可以称的次数,问最多可以在多少个球中可以称出坏球。由于题目并没有要求知道坏球的轻重,因此我们可以使用结论6,即N=(3^H - 1)/2,但是这里有一个/2,无法满足题目中的同余性质,我们当然可以使用大数运算,不过此题还有更加好的方法。我们设f(h)=(3^h - 1)/2,则f(h+1)=(3^(h+1)-1)/2,不难得到f(h+1)=f(h)+3^h,那这样的话就可以使用同余性质了。但是h的范围在10^9,直接线性的循环肯定挂了。其实不难想象这个数列有循环节,写个程序就可以找到了,循环节是464。

3. pku 1029 False coin 

这个题目是给定了n个球,其中有一个坏球,重量未知,然后给出K组称量结果,问最后的坏球是哪一个,这个题目直接做比较烦琐,我直接枚举第i个球是坏球,并且是轻还是重来做,最后再判断的,时间复杂度O(n * k * 2)