字節二面智力題: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 愛分享」,更多技術面試深度解析,我們下篇見。

文章首發地址


原文出處:https://juejin.cn/post/7659936053578465315


精選技術文章翻譯,幫助開發者持續吸收新知。

共有 0 則留言


精選技術文章翻譯,幫助開發者持續吸收新知。
🏆 本月排行榜
🥇
站長阿川
📝18   💬3   ❤️5
755
🥈
我愛JS
📝2   💬5   ❤️3
143
評分標準:發文×10 + 留言×3 + 獲讚×5 + 點讚×1 + 瀏覽數÷10
本數據每小時更新一次
📢 贊助商廣告 · 我要刊登