记得这是在大四上半年晚上开卧谈会的时候我们宿舍一个大能人给我们出的题,今天突然想起来:
从前有一个村庄,村庄里有若干个村民,村民都非常的聪明,对于各种复杂的问题他们都能够仔细的观察,并能做出你所能做的一切分析和判断,他们每个人都养且仅养一条狗。有一天,所有的村民接到了一条确切的消息:村里的狗中有若干条得了一种病(这种病不会传染)。要求由且仅由这些村民自己找出这些病狗,他们每天上午要检查除了自己的狗以外所有的狗。村民之间不许交谈,如果一个村民通过观察分析,判断出了自己的狗是病狗,那他就开枪打死这只狗,但任何人不许打死别人的狗。排查工作就这样开始了,第一天没有枪响,第二天也没有枪响,第三天的正午,所有人都听到了“砰……”的一阵枪响。请问:村子里共有多少条病狗?
后来知道了这个问题是
IBM
公司的一道面试题。答案是
3
条。解决的方法如下,按假设病狗数量不断推论:
假设病狗数为
1
,那么在第一天这条病狗的主人就会发现:除了他自己的狗以外所有的狗都没有病,然而病狗确实是存在的,因此这个村民就会做出推断,自己的狗就是病狗。他就会开枪打死它。然而第一天没有枪响,我们要继续假设。
假设病狗数为
2
,大多数人都会发现这
2
条病狗,但会有且仅会有两个村民只看到了
1
条病狗(因为他们自己的狗也是病狗,显然地,他们所看到的病狗是彼此对方的)。我们考虑这两个村民中的一个人,在第一天,他暂时还不能断定自己的狗是否有病,但他可以假设:他所看到的这条病狗就是村里唯一的病狗;然后就此做出上一自然段(假设病狗数为
1
)中的分析:如果真的是这样,那这个病狗的主人也会发现自己的狗是病狗(因为病狗的主人不会看到其他的狗生病)。在今晚,病狗的主人就会把它处死。然而,在他第二天出去检查的时候,发现所有的狗都活得好好的。他会做出判断:先前的假设是错误的,村子里的病狗不仅仅是一条,但是第一天在他去检查时的确仅发现了
1
条病狗,因此很明显地,自己的狗一定就是病狗。这条可怜的狗也会被处决。但是第二天仍没有枪响。需要继续假设。
假设病狗数为
3
,大多数人会看到
3
条病狗,有
3
位村民只看到
2
条。在你做出分析的同时,村民也在进行着同样缜密的推理。这
3
位村民会做出上一自然段(假设病狗数为
2
)中的分析,他们一定知道,如果第二天有狗被处决的话,那么他们的假设就成立。然而等到了第三天去检查的时候,发现没有狗被处死,那足以证明自己的狗也是病狗。他们会在第三天开枪。假设成立,原题得解。
你也许能够发现,上述三段分析中,后一段都会借助前边的那一段来分析。这俨然是一个递归问题。假设病狗数为
n
,如果
n==0
则执行操作,跳出递归,如果
n>0
则递归
(n-1)
的情况。把当前的状况用一个三元组来表示
(
第
d
天
,
总共看到
t
条狗
,
其中有
s
条有病
)
,下面是伪代码:
bool assume(day, total, sick) {
if ( sick == 0 ) { shoot(hisDog); return true; }
else {
if( assume(day+1, total-1, sick-1) ) return false;
else { shoot(hisDog); return true; }
}
今天早上起来发现新买的
n73
不见了,可把我给急坏了,我拿来笤帚用笤帚把在床底下不断地扫,最后只扫出了几个玻璃球、一只袜子、几张涂满鸦的破纸,一大堆土。后来发现桌上躺着那个
old pal
:
2610
,我才恍然大悟,原来是个梦啊。哼哼,太有意思了。
都说有钱人,尤其是实打实地干出来的有钱人从来不乱花钱,他们的钱都是血汗,哪舍得花啊,哪有时间花啊。乱花钱,那是纨绔子弟,是暴发户。北京月入
10k
的大牛还有挤公交车的,人家
手机之父
马丁
•
库贝先生还会用几百块钱(折合成人民币)的破手机呢。
我还是个并且在未来的很长时间以内都将是个对当前的不好不坏的日子很满足但是对未来的美好生活充满期待的穷光蛋……