智力題(程式設計師面試經典)

愛貓狗的小郝發表於2020-02-06

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行。
在這裡插入圖片描述
要蓋住每一行,總有一塊骨牌必須鋪至下一行。無論嘗試多少次、多少種方法,我們都無法成功鋪下所有骨牌。
其實,還有更簡潔更嚴謹的證明說明為什麼不可能。棋盤原本有32個黑格和32個白格。將對角角落上的兩個方格(相同顏色)切掉,棋盤只剩下30個同色的方格和32個另一種顏色的方格。為方便論證起見,我們假定棋盤上剩下30個黑格和32個白格。
放在棋盤上的每塊骨牌必定會蓋住一個白格和一個黑格。因此,31塊骨牌正好蓋住31個白格和31個黑格。然而,這個棋盤只有30個黑格和32個白格,所以,31塊骨牌蓋不住整個棋盤。

NO.3
 有兩個水壺,容量分別為5夸脫(美製:1夸脫=0.946升,英制:1夸脫=1.136升)和3夸脫,若水的供應不限量(但沒有量杯),怎麼用這兩個水壺得到剛好4夸脫的水?注意,這兩個水壺呈不規則形狀,無法精準地裝滿“半壺”水。
解法
根據題意,我們只能使用這兩個水壺,不妨隨意把玩一番,把水倒來倒去,可以得到如下順序組合:
在這裡插入圖片描述
注意,許多智力題其實都隱含數學或電腦科學的背景,這個問題也不例外。只要這兩個水壺的容量互質(即兩個數沒有共同的質因子),我們就能找出一種倒水的順序組合,量出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次(從21到29 一次次試)。若雞蛋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。 (直接設要X次,假如X 和X-1這兩次了
則再加X-2 總共還是X次, 次數總為X)我們先從14層開始,然後是27層,接著是39層,依此類推,最差情況下雞蛋要扔14次。 正如解決其他許多最大化/最小化的問題一樣,這類問題的關鍵在於“平衡最差情況”。

NO.6  
走廊上有100個關上的儲物櫃。有個人先是將100個櫃子全都開啟。接著,每數兩個櫃子關上一個。然後,在第三輪時,再每隔兩個就切換第三個櫃子的開關狀態(也就是將關上的櫃子開啟,將開啟的關上)。照此規律反覆操作100次,在第i輪,這個人會每數i個就切換第i個櫃子的狀態。當第100輪經過走廊時,只切換第100個櫃子的開關狀態,此時有幾個櫃子是開著的? 解法 要解決這個問題,我們必須弄清楚所謂切換儲物櫃開關狀態是什麼意思。這有助於我們推斷最終哪些櫃子是開著的。 1. 問題:櫃子會在哪幾輪切換狀態(開或關)? 櫃子n會在n的每個因子(包括1和n本身)對應的那一輪切換狀態。也就是說,櫃子15會在第1、3、5和15輪開或關一次。(i=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的平方: 11, 22, 33, …, 1010 因此,最後共有10個櫃子是開著的。

相關文章