字节二面智力题:100只老虎和1只羊关在一起,这只羊会不会被吃?

上周有个朋友来找我,说去面字节广告与交易后端开发岗,一面过了,二面,本来聊得好好的,聊到了项目经历、系统设计,然后面试官突然话锋一转,说给你出道智力题。

题目是这样的。

N 只老虎,和 1 只羊,关在一起。

规则有那么几条。

老虎可以吃草,但更愿意吃羊。每次只能有 1 只老虎吃羊。吃了羊之后,那只老虎会变成羊。所有老虎都非常聪明,完全理性,第一目标是保证自己活下来。

问,当 N=100 的时候,这只羊会不会被吃?

我朋友说,他愣在那儿大概有两三秒。

不是完全不会,是脑子一下子有点转不过来,100 只老虎,1 只羊,这题听起来就像是,羊肯定没了。

但直觉告诉他的答案,往往就是错的。


我后来自己推了一遍,发现这道题的妙处,不在答案本身,而在推的过程中那种,一层一层剥开的感觉。

先从最简单的情况开始想。

N=1,只有 1 只老虎,1 只羊。

老虎吃不吃?

吃。

吃完变成羊,但现在没有其他老虎了,那这只新羊可以安安稳稳吃草活下去,没有任何威胁。

所以 N=1,羊被吃。


N=2,2 只老虎,1 只羊。

事情开始变得有意思了。

假设老虎甲动了吃羊的念头。它想,我吃了羊,我变成羊,但现在还有老虎乙在,那我这只新羊,不就会被老虎乙吃掉吗?

老虎乙也是这么想的。

所以,任何一只老虎如果吃了羊,它马上就会变成那只被剩下的老虎眼中的猎物。

聪明的老虎不会这么干。

两只老虎对视一眼,默契地转身,去啃草了。

羊没被吃。


N=3,3 只老虎,1 只羊。

假设老虎甲吃了羊,变成羊。现在场上是 2 只老虎 + 1 只新羊。

这就是 N=2 的情况,我们刚刚推过,N=2 的时候羊不会被吃。

也就是说,老虎甲吃了羊之后,它变成的那只新羊,是安全的。

既然安全,那为什么不呢?

老虎甲会吃,老虎乙和老虎丙也会这么想。

N=3,羊被吃。


N=4,4 只老虎,1 只羊。

老虎甲吃了羊,变成羊,场上变成 3 只老虎 + 1 只新羊,也就是 N=3 的情况。

N=3,羊会被吃。

那意味着,老虎甲变成新羊之后,它自己会被其他老虎吃掉。

所以它不吃。其他三只老虎也是完全一样的计算逻辑。

羊没被吃。


推到这里,你大概已经看出来规律了。

奇数只老虎,羊会被吃。

偶数只老虎,羊不会被吃。

奇数,吃。偶数,不吃。

规律就这么简单。

但等等,你把 N 往上加一加,N=5,N=6,N=7,N=8,规律一直成立吗?

成立。

因为每一只老虎在做决策的时候,它脑子里运行的都是同一套递推逻辑,如果我吃了羊,下一个状态是 N-1 只老虎加 1 只羊,那个状态安全吗?

安全就吃,不安全就不吃。

这套从最后一个状态往前推的思维方式,博弈论里有个名字,叫逆向归纳。


好,现在回到面试官的问题,N=100。

100 是偶数。

任何一只老虎如果吃了羊,剩下的就是 99 只老虎加上它变成的那只新羊。

N=99,奇数,羊会被吃。

也就是说,它变成了那只羊之后,它自己会被吃掉。

所以没有任何一只老虎会动手。

100 只老虎,全部选择啃草。

那只羊,就这么在 100 只虎视眈眈的老虎中间,安然无恙地活下来了。


说到这里,我忍不住想强调一下这件事的反直觉程度。

100 只老虎。

你直觉上觉得羊活不了,对吧?

但推完逻辑之后发现,老虎越多,羊反而越安全。

N=1,羊死了。

N=2,羊活了。

N=3,羊死了。

N=4,羊活了。

N=5,羊死了。

N=6,羊活了。

你发现规律没?只要 N 是偶数,羊就活,而且这个规律对所有更大的偶数都成立,不会因为老虎变多就突然失效。

99 只老虎,羊死。

100 只老虎,羊活。

就差一只老虎的差距,命运完全翻转。

这种感觉,就好像你写了一行代码,off-by-one,整个系统行为完全不一样了。

卧槽。


这道题背后到底是什么?

我觉得面试官考的,不是你知不知道这道经典题的答案,而是在看你面对一个看起来复杂的问题时,会不会本能地找到那个最简单的起点。

很多人拿到这道题,第一反应是试图直接分析 N=100 的情况,100 只老虎,脑子直接炸了。

但正确的打开方式,是先把问题缩小到最小规模,N=1,N=2,看看发生了什么,然后找规律,再证明规律。

这就是数学归纳法,也是程序员最熟悉的思维方式。

你写一个递归函数,不也是先写 base case,再写递推关系吗?

说真的,这道题拆到最后,就是一个递归函数。

kotlin 复制代码
willSheepBeEaten(N):
  if N == 1: return true
  if N == 2: return false
  return !willSheepBeEaten(N-1)

三行,核心逻辑全在里面了。


再往深一层想,这道题其实也在考你对「平衡」的直觉。

100 只老虎都不吃羊,这是一个纳什均衡,说得更准一点,是子博弈完美纳什均衡。

意思是,在这个平衡状态下,没有任何一只老虎可以通过单方面改变自己的策略(去吃羊)来获得更好的结果(活下来)。

所有老虎都理性,所有老虎都知道其他老虎理性,这个共识本身,反而保护了一只谁都不愿意保护的羊。

这种「所有人的理性选择加在一起,产生了一个谁都没想到的结局」,在后端系统里其实也有类似的东西。

比如分布式系统里的拜占庭容错,每个节点都不确定其他节点是不是在发错误消息,但正因为大家都不确定,整个系统反而通过投票机制达成了共识。

再比如微服务架构里的熔断机制,每个服务都「理性地」选择在自己扛不住的时候断开,反而让整个系统避免了雪崩。

单个节点的理性决策,在系统层面产生了一个反直觉的结果。

这道题,某种程度上,就是在考你有没有这种,从单个决策跳到系统层面思考的直觉。


说回我那个朋友。

他最后也没拿到这个 offer。

但他说,出来之后他又想了一遍这道题,觉得最有意思的不是答案,而是面试官在看他推导的过程中,一直在观察他的思考路径。

先推 N=1,再推 N=2,然后说「我好像看到规律了」,再把奇偶性的结论说出来,最后解释为什么。

这一套路径展示出来,比直接报一个「偶数不吃」的答案,值钱得多。


所以,如果你在面试的时候遇到了这道题。

别急着报答案。

你可以先跟面试官说,「我先想想最简单的情况」,然后从 N=1 开始,一步一步推给面试官看。

推到 N=3 的时候,可以停一下,说,「我觉得规律出来了,奇数吃,偶数不吃,我验证一下 N=4」,验证完,再说结论。

面试官想看的不是你对不对,而是你有没有这种,把复杂问题拆成最小单元、一步步递推的工程师思维。

这才是这道题真正值钱的部分。


100 只老虎,1 只羊,羊活得好好的。

这道题我到现在还是觉得挺妙的,妙在它用一个看起来很荒唐的场景,把逆向归纳、纳什均衡、系统思维这些硬核东西,全部装进去了。

而且它还有一个隐藏的温柔。

有时候,最好的保护,不是谁来英雄救美,而是这个系统里,所有参与者都足够聪明,以至于谁都不敢先动手。

想想还挺有意思的。


如果这篇内容对你有启发,欢迎关注「Fox爱分享」,更多技术面试深度解析,我们下篇见。

文章首发地址

相关推荐
xin(n_n)b1 小时前
经典题目(3):把数字翻译成字符串;兑换零钱
算法
学iOS很快乐2 小时前
Pinterest Staff SDE 五轮面试全过,加拿大 TC 500K CAD,附 OA 真题和每轮考点
面试·职场和发展
惊鸿一博2 小时前
特征匹配+Glue Factory 框架评估特征提取与匹配算法时常用的度量标准
算法·特征匹配
柒和远方2 小时前
LeetCode 4. 寻找两个正序数组的中位数 —— 二分划分的艺术
javascript·python·算法
修己xj2 小时前
C盘又爆红了?将Windows桌面路径迁移到其他盘,瞬间清爽!
程序员
hyunbar7772 小时前
华为云DWS磁盘使用率超90%后集群只读
程序员
z小猫不吃鱼3 小时前
模型剪枝经典论文精读:Channel Pruning for Accelerating Very Deep Neural Networks
算法·机器学习·剪枝
njsgcs3 小时前
已知链中心距用节数算中间电机摆放位置 常量弧长 三链轮弦长模型算法
算法
黄敬峰3 小时前
从“聊天”到“做事”:构建你的第一个高性能 LangChain Agent
面试