面试智力题
1. 砝码称重问题
问题1
- 有十组砝码,每组十个,其中九组每个砝码的重量为10g,另外一组每个砝码的重量为9g,问用一个能显示克数的秤,最少几次能找到这组9g的砝码?
分析
- 将砝码分为
1~10
组,第一组拿出1
个砝码,第二组拿出2
个砝码,第三组拿出3
个砝码,…,最后一组拿出10
个砝码,全部放到称上,显示的重量为y
,令x=550-y
,则第x
组就是砝码重量为x
的一组。
问题2
- 有一个天平,9个砝码,其中有1个比其他8个轻,问至少称几次能找到轻的那个砝码?
分析
-
将砝码分为3组,每组3个,拿其中两组到天平上称(第1次),如果一样重,则轻的为剩下那组,不一样重,则也能分辨出哪一组轻;
-
取轻的那一组的3个砝码,从中选出两个到天平上称(第2次),若一样重,则剩余的1个为轻,不一样重,则轻的也能轻易找到。
2. 水壶问题
问题1
- 现在有不限量的水,你有两个容量为5L和3L的罐子,请准确称出4L水。注意每次只能将罐子装满或者倒空,或者从一个罐子向另一个罐子倒水。
分析
- 需要解一个不定方程:
5 × a + 3 × b = 4 5 \times a + 3 \times b = 4 5×a+3×b=4
-
可以取 a = 2 , b = − 2 a = 2, b = -2 a=2,b=−2,则表明最终
5L
的罐子(记为A
)需要被灌满两次,4L
的罐子(记为B
)需要倒出两次,具体操作如下:-
将
A
加满,把A
中的水倒入B
中,然后将B
中的水倒掉,接着把A
中剩余的水倒入B
中,此时:A:0L、B:2L; -
将
A
加满,把A
中的水倒入B
中,然后将B
中的水倒掉,此时:A:4L、B:0L;
-
问题2
- 现在有不限量的水,你有两个容量为5L和6L的罐子,请准确称出3L水。
分析
- 需要解一个不定方程:
5 × a + 6 × b = 3 5 \times a + 6 \times b = 3 5×a+6×b=3
-
可以取 a = 3 , b = − 2 a = 3, b = -2 a=3,b=−2,则表明最终
5L
的罐子(记为A
)需要被灌满三次,4L
的罐子(记为B
)需要倒出两次,具体操作如下:-
将
A
加满,把A
中的水倒入B
中,此时:A:0L、B:5L; -
将
A
加满,把A
中的水倒入B
中,此时:A:4L、B:6L; -
把
B
中的水倒掉,此时:A:4L、B:0L; -
把
A
中的水倒入B
中,此时:A:0L、B:4L; -
将
A
加满,把A
中的水倒入B
中,此时:A:3L、B:6L; -
把
B
中的水倒掉,此时:A:3L、B:0L;
-
问题三
- 现在有不限量的水,你有两个容量为
x
和y
的罐子,请准确称出z
水。
分析
-
该问题是上述两个问题最一般化的问题。存在方案的充要条件:
z<=x+y
并且z
能整除gcd(x, y)
。 -
具体分析可以参考:【经典算法题】水壶问题。
3. 石子重量排序问题
问题
- 给你一堆外观相同的石子,但是重量不同,你还可以使用一个没有砝码的天平,问如何将这些石子升序排列?
分析
-
排序算法的关键在于可以比较两个数的大小即可,具体这两个数是多少无所谓。因此采用各种排序算法都可以。
-
可以使用快排:思路是找到每个石子所在的位置,可以将小于当前石子重量的石子放到左边,大于的放到右边,然后递归求解即可。
-
可以使用归并排序:初始认为每个石子是一堆,然后递归合并相邻两堆石子即可。
-
可以使用堆排序,使用
heapify
建大根堆,然后每次将堆顶元素放到最后,之后down(1)
即可。
4. 烧绳子
问题1
- 烧一根绳子要用1个小时,如何用这根绳子来判断半个小时?
分析
- 从两头开始烧即可,当烧完时就是半个小时。
问题2
- 烧一根绳子要用1个小时,你有若干条绳子,如何用烧绳来计时一个小时十五分钟呢?
分析
- 同时烧两根绳子,一根从一头烧,一根从两头烧;当两头烧的绳子烧完时(半小时),将一头烧的绳子的另一头点燃(此时已烧过半小时),这根绳子烧完时(十五分钟);从两头点燃第三根绳子,烧完时(半小时)共一小时十五分钟。
5. 硬币
问题
- 有10枚正面向上的硬币,10枚反面向上的硬币,混在一起。你需要闭上眼,同时你也摸不出一个硬币是正面向上,还是反面向上。你需要将这20枚硬币分成两堆,使得两堆中正面向上的的硬币数量相同,反面向上的的硬币数量也相同。
分析
-
必须分成数量相同的两堆,都是10个,然后将其中一堆全部翻转一下即可。
-
假设一堆中有
x
个正面向上,则另一堆有10-x
个正面向上,翻转后另一堆有x
个正面向上,满足条件。
6. 可怜的小猪
问题1
- 有
1000
桶水,其中只有一桶水有毒,你可以将水喂给小猪,只要小猪喝到有毒的水,就会死。你只能喂一轮(每桶水都处理过一次算作一轮)。问最小需要多少头小猪?如何确定有毒的那桶水?
分析
- 需要的小猪数目:
⌈ l o g 2 ( 1000 ) ⌉ = 10 \lceil log_2(1000) \rceil = 10 ⌈log2(1000)⌉=10
-
每桶水进行编号,对应
0~999
,可以将编号转化为二进制,对于每桶水来说,如果某个二进制位是1,则给对应的小猪喂这桶水。 -
最后判断哪些小猪死了,则对应的二进制位是1,没死的小猪对应的二进制位是0。这样就可以确定有毒的水的编号了。
问题
- 上述问题基本不变,唯一变化的是可以喂
k
轮。问最小需要多少头小猪?如何确定有毒的那桶水?
分析
- 需要的小猪数目:
⌈ l o g k + 1 ( 1000 ) ⌉ \lceil log_{k+1}(1000) \rceil ⌈logk+1(1000)⌉
- 提示:将每桶水当做一个
k+1
进制数。细节请参考:【经典算法题】可怜的小猪。
7. 鸡蛋的硬度
- 定义:如果鸡蛋在第
a
层楼扔下去不碎,但是在第a+1
层楼扔下去碎了,在鸡蛋硬度为a
(鸡蛋硬度小于等于楼层高度)。
问题一
- 100层楼,你有1个鸡蛋,为了测试出鸡蛋的硬度,需要扔多少次?
分析
- 因为只有一个鸡蛋,为了确保一定测试出鸡蛋的硬度,必须从第一层开始一层一层测试,因此最坏情况下需要测试100次(对应鸡蛋硬度为100)的情况。
问题二
- 100层楼,你有2个鸡蛋,为了测试出鸡蛋的硬度,需要扔多少次?
分析
-
参考网址:扔鸡蛋。
-
二分:第一个鸡蛋从第50层楼扔下去,另一个鸡蛋只能一层一层仍,最坏需要51次(对应硬度为100)。
-
平方根法:我们尝试每10层扔一次,第一次从10层扔,第二次从20层扔,第三次从30层…一直扔到100层。最坏的情况是在第100层碎掉,尝试次数为 10 + 9 = 19次。
-
数学做法:
-
假设最优解是
x
次,则第一次选择第x
层扔鸡蛋。不可能是x+1
层、或者x-1
层扔,因为如果蛋碎了,则分别需要x+1
次尝试、x-1
次尝试;x+1>x
,不是最优解,x-1
如果满足条件,则x
不是最优解,矛盾(这里其实还要考虑但没碎的情况,因此不能取x-1
)。 -
如果没碎,问题就变为了两个鸡蛋从
100-x
层楼往下扔,要求尝试的次数不超过x-1
次,因此需要在第x+x-1
层楼扔。 -
于是有:
x+(x-1)+...+1>=100
,上取整,可知x=14
。 -
因此最坏情况下,最小需要扔
14
可以测出鸡蛋的硬度。
-
问题三
n
层楼,m
个鸡蛋,为了测试出鸡蛋的硬度,需要扔多少次?
分析
-
这是一个动态规划的问题。
-
具体讲解请参考:【经典算法题】鸡蛋的硬度。
8. 灯泡开关
问题
- 有
n
个灯泡,开始都是亮的。进行n
轮操作,第一轮将所有1的倍数的灯泡开关按一下,第二次将所有2的倍数的灯泡开关按一下,…,问最后还有多少灯是亮着的?是哪些灯?
分析
-
一个灯泡
x
最后是亮的 ⟺ \iff ⟺它被按奇数次 ⟺ \iff ⟺它的约数个数是奇数。 -
因此最后所有约数个数是奇数个的灯泡是亮的,比如
5
个灯泡被按5
次,1、4
灯泡就是亮的,因为1
只有1
这一个约数,4
有1、2、4
三个约数。 -
下面考虑约数个数为奇数的数据有什么特点:如果一个数N可以质因数分解为 p 1 α 1 ∗ p 2 α 2 ∗ . . . ∗ p k α k p_1^{\alpha_1}*p_2^{\alpha_2}*...*p_k^{\alpha_k} p1α1∗p2α2∗...∗pkαk ,则N的约数个数为 ( α 1 + 1 ) ∗ ( α 2 + 1 ) ∗ . . . ∗ ( α k + 1 ) (\alpha_1+1)*(\alpha_2+1)*...*(\alpha_k+1) (α1+1)∗(α2+1)∗...∗(αk+1) 。则必须有 α i + 1 \alpha _ i + 1 αi+1必须是奇数,所以 α i \alpha_i αi必须是偶数,因此
N
是完全平方数。 -
上面证明了如果一个数
N
的约数个数为奇数,则其是完全平方数。反过来也成立(例如 x = y 2 x = y^2 x=y2,只有约数y
出现一次,其余都是成对出现的)。 -
因此本题的最后答案就是
1~n
中完全平方数的个数。
9. 构成三角形的概率
问题
- 给定一个长度为
1
的绳子,可以从中选择两个点截断,变成三段,问可以构成三角形的概率是多少?
分析
- 假设选择的两个点的坐标是
y、x
(y<x
),如下图:
- 则需要满足(两边之和大于第三边):
{ 1 − y > y x > 1 − x y + ( 1 − x ) > x − y \begin{cases} 1 - y > y \\ x > 1 - x \\ y + (1 - x) > x - y \end{cases} ⎩⎪⎨⎪⎧1−y>yx>1−xy+(1−x)>x−y
- 化简,有:
{ y < 1 2 x > 1 2 y > x − 1 2 \begin{cases} y < \frac{1}{2} \\ x > \frac{1}{2} \\ y > x - \frac{1}{2} \end{cases} ⎩⎪⎨⎪⎧y<21x>21y>x−21
方法一:线性规划
- 上述不等式对应的线性规划区域如下:
- 绿色和橙色是合法的总面积,橙色的为可以构成三角形的区域,因此改为为
1/4
。
方法二:二重积分
- 概率对应如下积分:
∫ 1 2 1 ∫ x − 1 2 1 2 d y d x / ∫ 0 1 ∫ 0 x d y d x = 1 8 / 1 2 = 1 4 \int _{\frac{1}{2}} ^{1} \int _{x-\frac{1}{2}} ^{\frac{1}{2}} dy \ dx \quad / \quad \int _{0} ^{1} \int _{0} ^{x} dy \ dx \\ = \frac{1}{8} / \frac{1}{2} = \frac{1}{4} ∫211∫x−2121dy dx/∫01∫0xdy dx=81/21=41
- 说明:部分参考网址:盘点面试中常见的智力题。