一些有趣的笔试题
腾讯 C++ 客户端研发实习生
有两个水杯,容积分别为 6 升和 5 升。试问可否只用这两个水杯量出 3 升水。
如果可以用第三个容器,那么这个问题就很简单了。我们可以量出 1 升水(先把 6 升的水杯灌满,再用其中的水把 5 升的水杯灌满),这样就能得到任意整数升水。面试时我就是这么回答的,现在觉得自己好蠢。果然我就是个自以为是的蠢货。
如果只能用这两个杯子,而不能用其他容器,也就是说通过一系列操作使得某个杯子中恰有 3 升水。这种情况也是有解的,而且并不难想到。先把 5 升的杯子灌满,再把这些水倒进 6 升的杯子中。再把 5 升的杯子灌满,然后用其中的水把 6 升的杯子灌满,此时 5 升的杯子中还有 4 升水。把 6 升的杯子倒空,将 5 升的杯子中的 4 升水倒进 6 升的杯子,再把 5 升的杯子灌满,然后用其中的水把 6 升的杯子灌满,这时 5 升的杯子中恰有 3 升水。这一番描述未免显得啰嗦。我们用有序二元组 \((x,y)\) 表示某时刻 5 升和 6 升的杯子中的水的体积,那上述过程可以表示为 (0, 0) -> (5, 0) -> (0, 5) -> (5, 5) -> (4, 6) -> (4, 0) -> (0, 4) -> (5, 4) -> (3, 6)。
通过上述分析,我们得出了只用这两个杯子量出 1, 3, 4, 5, 6 升水的办法。其实 2 升水也能量出。只要在上述操作之后接着 (3, 0) -> (0, 3) -> (5, 3) -> (2, 6) 即可。
自然地,我们有一个猜想,如果有两个体积为 \(A, B\) 的杯子(\(A, B\) 是正整数),那么我们可以只用这两个杯子量出体积为 \(\gcd(A, B), 2\gcd(A, B), 3, \gcd(A, B), \dots, \max(A, B)\) 的水。
阿里实习 C++ 研发
小明在公交车站等车。有三辆公交车 A,B,C 可供选择。A 车的到站时间在 0 到 10 分钟内均匀分布,B 车的到站时间在 0 到 20 分钟内均匀分布,C 车的到站时间在 0 到 30 分钟内均匀分布。求小明等候时长的期望。
\begin{aligned}
&-\int_{0}^{10} x\frac{\dif ((1 - x/10) ( 1- x/20) (1 - x/30)) } { \dif x} \dif x \\
&= -\int_{0}^{10} x {\dif ((1 - x/10) ( 1- x/20) (1 - x/30)) } \\
&= - \int_{0}^{10} \dif(x (1 - x/10) ( 1- x/20) (1 - x/30) ) - (1 - x/10) ( 1- x/20) (1 - x/30) \dif x \\
&= \int_{0}^{10} (1 - x/10) ( 1- x/20) (1 - x/30) \dif x \\
&= \frac{15}{4}
\end{aligned}
给定 \(n\) 个 \(1\) 到 \(31\) 之间的正整数。现在要把这 \(n\) 个数分成若干组,要求每组内的数之和不超过 32 。试问至少需要分成多少组。(未说明数据范围)
旷视电话面
经典问题:判断链表是否有环。找环起点。
设链表长为 \(n\)。
要求:
- 时间复杂度 \(O(n)\)
- 空间复杂度 \(O(1)\)
扩展:给定 \(n+1\) 个整数,这些数都在 \(1\) 到 \(n\) 之间。已知有且只有一个数出现了不止一次,试找出这个数。
要求:
- 不允许修改输入的数组
- 时间复杂度 \(O(n)\)
- 空间复杂度 \(O(1)\)
(已解决)
腾讯实习
有 \(n\) 种面值的硬币(\(n \le 100\)),每种面值的硬币都有无限多个。要组合出 \(1\) 到 \(m\)($ m \le 10^9$) 之间的所有数额,至少需要多少个硬币。若无法组合出全部数额则输出 -1。(已解决)
微软实习
给定一个整数序列,每次可以取出一个回文子序列,问最少取多少次可以把整个序列取完。
平面上有一些花,一些蜜罐,一个蜂窝,给定它们的坐标。一只蜜蜂从蜂窝出发,飞到一朵花那里采一个单位的蜜,再飞到某个蜜罐处将蜜卸到蜜罐里,再飞到另一朵花处,采蜜,飞到某个蜜罐卸下蜂蜜,如此循环,最后回到蜂窝。如果蜜蜂最多能飞 \(R\) 单位距离(欧几里得距离),试求出最多能采到多少蜂蜜。注意:每朵花只能采一次,但可以多次往一个蜜罐里卸蜂蜜。
(今年微软的四个笔试题貌似都没给数据范围并且没给时限和内存限制)
百度实习
给定一个长为 \(n\) 的字符串 \(S\),由大小写字母和数字组成。给定常数 \(k\) 。试判断是否存在 \(S\) 的某个排列满足任意相邻的两个相同字符之间至少有 \(k\) 个其他字符。若能,输出字典序最小的方案,若不能输出 "-1"。
华为实习
一个 \(40 \times 50\) 的网格,每个网格要么是空的,要么有一个水果。有以下四种操作:
- 将某一行内的水果全部切开
- 将某一列内的水果全部切开
- 45度斜着切(两种情况)
试问最少切多少刀能把所有水果都切开。
题目明确说水果数量不超过 36。
这个问题是 set cover problem 的一个特列,也许是 NPC 的。