首页 > 剑指offer > [答案]来自苹果、谷歌、微软等知名公司六道有趣智力面试题
2013
12-04

[答案]来自苹果、谷歌、微软等知名公司六道有趣智力面试题

NO.1

有20瓶药丸,其中19瓶装有1克/粒的药丸,余下一瓶装有1.1克/粒的药丸。给你一台称重精准的天平,怎么找出比较重的那瓶药丸?天平只能用一次。

解法

有时候,严格的限制条件有可能反倒是解题的线索。在这个问题中,限制条件是天平只能用一次。

因为天平只能用一次,我们也得以知道一个有趣的事实:一次必须同时称很多药丸,其实更准确地说,是必须从19瓶拿出药丸进行称重。否则,如果跳过两瓶或更多瓶药丸,又该如何区分没称过的那几瓶呢?别忘了,天平只能用一次。

那么,该怎么称重取自多个药瓶的药丸,并确定哪一瓶装有比较重的药丸?假设只有两瓶药丸,其中一瓶的药丸比较重。每瓶取出一粒药丸,称得重量为2.1克,但无从知道这多出来的0.1克来自哪一瓶。我们必须设法区分这些药瓶。

如果从药瓶#1取出一粒药丸,从药瓶#2取出两粒药丸,那么,称得重量为多少呢?结果要看情况而定。如果药瓶#1的药丸较重,则称得重量为3.1克。如果药瓶#2的药丸较重,则称得重量为3.2克。这就是这个问题的解题窍门。

称一堆药丸时,我们会有个“预期”重量。而借由预期重量和实测重量之间的差别,就能得出哪一瓶药丸比较重,前提是从每个药瓶取出不同数量的药丸。

将之前两瓶药丸的解法加以推广,就能得到完整解法:从药瓶#1取出一粒药丸,从药瓶#2取出两粒,从药瓶#3取出三粒,依此类推。如果每粒药丸均重1克,则称得总重量为210克(1 + 2 + … + 20 = 20 * 21 / 2 = 210),“多出来的”重量必定来自每粒多0.1克的药丸。

药瓶的编号可由算式(weight – 210 grams) / 0.1 grams得出。因此,若这堆药丸称得重量为211.3克,则药瓶#13装有较重的药丸。

NO.2

有个8×8棋盘,其中对角的角落上,两个方格被切掉了。给定31块多米诺骨牌,一块骨牌恰好可以覆盖两个方格。用这31块骨牌能否盖住整个棋盘?请证明你的答案(提供范例,或证明为什么不可能)。

解法

乍一看,似乎是可以盖住的。棋盘大小为8×8,共有64个方格,但其中两个方格已被切掉,因此只剩62个方格。31块骨牌应该刚好能盖住整个棋盘,对吧?

尝试用骨牌盖住第1行,而第1行只有7个方格,因此有一块骨牌必须铺至第2行。而用骨牌盖住第2行时,我们又必须将一块骨牌铺至第3行。

enter image description here

要盖住每一行,总有一块骨牌必须铺至下一行。无论尝试多少次、多少种方法,我们都无法成功铺下所有骨牌。

其实,还有更简洁更严谨的证明说明为什么不可能。棋盘原本有32个黑格和32个白格。将对角角落上的两个方格(相同颜色)切掉,棋盘只剩下30个同色的方格和32个另一种颜色的方格。为方便论证起见,我们假定棋盘上剩下30个黑格和32个白格。

放在棋盘上的每块骨牌必定会盖住一个白格和一个黑格。因此,31块骨牌正好盖住31个白格和31个黑格。然而,这个棋盘只有30个黑格和32个白格,所以,31块骨牌盖不住整个棋盘。

NO.3

有两个水壶,容量分别为5夸脱(美制:1夸脱=0.946升,英制:1夸脱=1.136升)和3夸脱,若水的供应不限量(但没有量杯),怎么用这两个水壶得到刚好4夸脱的水?注意,这两个水壶呈不规则形状,无法精准地装满“半壶”水。

解法

根据题意,我们只能使用这两个水壶,不妨随意把玩一番,把水倒来倒去,可以得到如下顺序组合:

enter image description here[+]查看原图

注意,许多智力题其实都隐含数学或计算机科学的背景,这个问题也不例外。只要这两个水壶的容量互质(即两个数没有共同的质因子),我们就能找出一种倒水的顺序组合,量出1到2个水壶容量总和(含)之间的任意水量。

NO.4

有个岛上住着一群人,有一天来了个游客,定了一条奇怪的规矩:所有蓝眼睛的人都必须尽快离开这个岛。每晚8点会有一个航班离岛。每个人都看得见别人眼睛的颜色,但不知道自己的(别人也不可以告知)。此外,他们不知道岛上到底有多少人是蓝眼睛的,只知道至少有一个人的眼睛是蓝色的。所有蓝眼睛的人要花几天才能离开这个岛?

解法

下面将采用简单构造法。假定这个岛上一共有n人,其中c人有蓝眼睛。由题目可知,c > 0。

1. 情况c = 1:只有一人是蓝眼睛的

假设岛上所有人都是聪明的,蓝眼睛的人四处观察之后,发现没有人是蓝眼睛的。但他知道至少有一人是蓝眼睛的,于是就能推导出自己一定是蓝眼睛的。因此,他会搭乘当晚的飞机离开。

2. 情况c = 2:只有两人是蓝眼睛的

两个蓝眼睛的人看到对方,并不确定c是1还是2,但是由上一种情况,他们知道,如果c = 1,那个蓝眼睛的人第一晚就会离岛。因此,发现另一个蓝眼睛的人仍在岛上,他一定能推断出c = 2,也就意味着他自己也是蓝眼睛的。于是,两个蓝眼睛的人都会在第二晚离岛。

3. 情况c > 2:一般情况

逐步提高c时,我们可以看出上述逻辑仍旧适用。如果c = 3,那么,这三个人会立即意识到有2到3人是蓝眼睛的。如果有两人是蓝眼睛的,那么这两人会在第二晚离岛。因此,如果过了第二晚另外两人还在岛上,每个蓝眼睛的人都能推断出c = 3,因此这三人都有蓝眼睛。他们会在第三晚离岛。

不论c为什么值,都可以套用这个模式。所以,如果有c人是蓝眼睛的,则所有蓝眼睛的人要用c晚才能离岛,且都在同一晚离开。

NO.5

有栋建筑物高100层。若从第N层或更高的楼层扔下来,鸡蛋就会破掉。若从第N层以下的楼层扔下来则不会破掉。给你2个鸡蛋,请找出N,并要求最差情况下扔鸡蛋的次数为最少。

解法

我们发现,无论怎么扔鸡蛋1(Egg 1),鸡蛋2(Egg 2)都必须在“破掉那一层”和下一个不会破掉的最高楼层之间,逐层扔下楼(从最低的到最高的)。例如,若鸡蛋1从5层和10层楼扔下没破掉,但从15层扔下时破掉了,那么,在最差情况下,鸡蛋2必须尝试从11、12、13和14层扔下楼。

具体做法

首先,让我们试着从10层开始扔鸡蛋,然后是20层,等等。

 如果鸡蛋1第一次扔下楼(10层)就破掉了,那么,最多需要扔10次。

 如果鸡蛋1最后一次扔下楼(100层)才破掉,那么,最多要扔19次(10、20、…、90、100层,然后是91到99层)。

这么做也挺不错,但我们只考虑了绝对最差情况。我们应该进行“负载均衡”,让这两种情况下扔鸡蛋的次数更均匀。

我们的目标是设计一种扔鸡蛋的方法,使得扔鸡蛋1时,不论是在第一次还是最后一次扔下楼才破掉,次数越稳定越好。

(1) 完美负载均衡的方法应该是,扔鸡蛋1的次数加上扔鸡蛋2的次数,不论什么时候都一样,不管鸡蛋1是从哪层楼扔下时破掉的。 
(2) 若有这种扔法,每次鸡蛋1多扔一次,鸡蛋2就可以少扔一次。 
(3) 因此,每丢一次鸡蛋1,就应该减少鸡蛋2可能需要扔下楼的次数。例如,如果鸡蛋1先从20层往下扔,然后从30层扔下楼,此时鸡蛋2可能就要扔9次。若鸡蛋1再扔一次,我们必须让鸡蛋2扔下楼的次数降为8次。也就是说,我们必须让鸡蛋1从39层扔下楼。 
(4) 由此可知,鸡蛋1必须从X层开始往下扔,然后再往上增加X1层……直至到达100层。 
(5) 求解方程式X + (X1) + (X2) + … + 1 = 100,得到X (X + 1) / 2 = 100 → X = 14。

我们先从14层开始,然后是27层,接着是39层,依此类推,最差情况下鸡蛋要扔14次。

正如解决其他许多最大化/最小化的问题一样,这类问题的关键在于“平衡最差情况”。

NO.6

走廊上有100个关上的储物柜。有个人先是将100个柜子全都打开。接着,每数两个柜子关上一个。然后,在第三轮时,再每隔两个就切换第三个柜子的开关状态(也就是将关上的柜子打开,将打开的关上)。照此规律反复操作100次,在第i轮,这个人会每数i个就切换第i个柜子的状态。当第100轮经过走廊时,只切换第100个柜子的开关状态,此时有几个柜子是开着的?

解法

要解决这个问题,我们必须弄清楚所谓切换储物柜开关状态是什么意思。这有助于我们推断最终哪些柜子是开着的。

1. 问题:柜子会在哪几轮切换状态(开或关)?

柜子n会在n的每个因子(包括1和n本身)对应的那一轮切换状态。也就是说,柜子15会在第1、3、5和15轮开或关一次。

2. 问题:柜子什么时候还是开着的?

如果因子个数(记作x)为奇数,则这个柜子是开着的。你可以把一对因子比作开和关,若还剩一个因子,则柜子就是开着的。

3. 问题:x什么时候为奇数?

若n为完全平方数,则x的值为奇数。理由如下:将n的两个互补因子配对。例如,如n为36,则因子配对情况为:(1, 36)、(2, 18)、(3, 12)、(4, 9)、(6, 6)。注意,(6, 6)其实只有一个因子,因此n的因子个数为奇数。

4. 问题:有多少个完全平方数?

一共有10个完全平方数,你可以数一数(1、4、9、16、25、36、49、64、81、100),或者,直接列出1到10的平方:

1*1, 2*2, 3*3, …, 10*10

因此,最后共有10个柜子是开着的。


  1. 题本身没错,但是HDOJ放题目的时候,前面有个题目解释了什么是XXX定律。
    这里直接放了这个题目,肯定没几个人明白是干啥

  2. 可以根据二叉排序树的定义进行严格的排序树创建和后序遍历操作。如果形成的排序树相同,其树的前、中、后序遍历是相同的,但在此处不能使用中序遍历,因为,中序遍历的结果就是排序的结果。经在九度测试,运行时间90ms,比楼主的要快。

  3. Thanks for using the time to examine this, I truly feel strongly about it and enjoy finding out far more on this subject matter. If achievable, as you achieve knowledge

  4. 学算法中的数据结构学到一定程度会乐此不疲的,比如其中的2-3树,类似的红黑树,我甚至可以自己写个逻辑文件系统结构来。

  5. Pingback: 来自苹果、谷歌、微软等知名公司六道有趣智力面试题,试试吧! | Acm之家