`
yuanlanjun
  • 浏览: 1185500 次
文章分类
社区版块
存档分类
最新评论

面试智力题:硬币问题

 
阅读更多

题目一:

你的面前有30个硬币,其中有10个正面朝上,20个反面朝上,混乱在一团。
要求:现在用厚布遮住你的眼睛。要你把30个硬币分成2团,每团正面朝上的硬币个数相等。问:你要怎么分?不能用手去触摸感觉,也没有其他人帮忙。

题目二:

有4枚硬币,初始状态未知。你的眼睛被蒙住,看不到硬币的状态,但可以随便翻任何几个硬币。你每翻一次以后,如果4枚硬币的状态是全正面朝上或者全背面朝上,旁边的人会告诉你翻成功了。现在问你,最少翻几次可以保证成功?每次翻哪几枚?(百度2008年面试题)

我们用4位二进制数表示硬币的状态。由于最终的结果只要4枚硬币状态一样就行,正面还是背面没有关系,因此0000或1111都可以成功。由此又可以推出任何两个互为反码的状态是等价的,比如1001和0110,对于我们的目标来讲没有区别。因此也不必关心0和1代表的是正面还是背面,只要知道他们的位置关系就可以。

用X和O来表示翻硬币的方法。X表示把相应位置的硬币翻过来,O表示保持不动。同样的,互为补码的翻法是等价的,比如XXOO和OOXX对结果没有区别。

下面我们看看任一时刻,4枚硬币的状态一共有几种:

0001
0010
0100
1000
1100
1010
1001

除了成功状态以外,一共就只有这7种状态,其他的所有状态都和这7种中的某一种等价。同样的可以知道,翻法也只有7种。现在我们再取4枚硬币,把它们叫做演示硬币(相应的,原来的那4枚称作原始硬币),让演示硬币的初始状态为0000。我们每一次对原始硬币使用了什么翻法,就对演示硬币执行同样的操作。举个例子:如果原始硬币的初始状态为0010,第一次翻的时候用OOXO的翻法,那么翻过一次以后,原始硬币状态变成0000,演示硬币变成0010。

可以看到,在任一时刻,当且仅当演示硬币的状态和原始硬币的初始状态相同时,翻成功。而原始硬币一共有7种初始状态。因此,要保证成功,就必须使演示硬币能呈现出所有7种状态,这样才能保证原始硬币无论具有哪种初始状态都一定会在某一步成功。故最少需要7步。翻法如下:

步骤 翻法 翻过以后演示硬币的状态
第1步 OOOX 0001
第2步 OOXX 0010
第3步 OXXO 0100
第4步 XXOO 1000
第5步 OXOO 1100
第6步 OXXO 1010
第7步 OOXX 1001

第二问:现在将4枚硬币排成正方形(2*2的矩阵),每翻过一次以后,旁边有个人会将整个硬币图案旋转90度的任意倍数。有没有办法仍然保证能翻成功?最少需要几步?

面试官说20分钟内能解出这道题的人是天才。不过就我看来,找到解题的思路并不困难。

由于每一次都会随机的旋转,所以硬币的某个状态旋转成各种角度都是等价的,也就是说,下面每一行的状态都是等价的:

状态A 0 1
0 0
1 0
0 0
0 0
0 1
0 0
1 0
状态B 1 1
0 0
1 0
1 0
0 1
0 1
0 0
1 1
状态C 0 1
1 0
1 0
0 1

可以看到,事实上只有3种不同的状态。同样的,由于在翻硬币之前会旋转,所以我们根本无法知道自己翻了哪一个硬币,只知道自己翻了几个,怎么排列。所以实际上只有3种翻法,和3种状态正好是类似的。

翻法x O X
O O
X O
O O
O O
O X
O O
X O
翻法y X X
O O
X O
X O
O X
O X
O O
X X
翻法z O X
X O
X O
O X

下面分析对每一种状态,执行每一种翻法之后会变成什么状态。结果单元格对应行是初始状态,列是翻法。用end表示成功(全0),“/”分隔几种可能的状态。

x<wbr> O X<br><wbr><wbr> O O</wbr></wbr></wbr> y<wbr> X X<br><wbr><wbr> O O</wbr></wbr></wbr> z<wbr> O X<br><wbr><wbr> X O</wbr></wbr></wbr>
A<wbr> 0 1<br><wbr><wbr> 0 0</wbr></wbr></wbr> B/C/end A A
B<wbr> 1 1<br><wbr><wbr> 0 0</wbr></wbr></wbr> A C/end B
C<wbr> 0 1<br><wbr><wbr> 1 0</wbr></wbr></wbr> A B end

最后一行是突破的关键点,因为对C状态进行z翻法必定会结束,而其他的都不能保证结束。那么,我们的策略是想办法让A和B转换成C,然后用z就结束了。整个翻法如下:(列出每一种初始状态在进行到一定步数后的状态)

步骤 翻法 初始状态A 初始状态B 初始状态C
第1步 z A B end
第2步 y A C/end
第3步 z A end
第4步 x B/C/end
第5步 z B/end
第6步 y C/end
第7步 z end

最少7步保证结束。另外给出最少步数的证明:因为在不旋转的情况下都最少要7步,所以旋转情况下的步数不可能比7步少,否则的话就可以用旋转的解法来解决不旋转的问题,故最少需要7步。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics