Google賽馬問題

Avril發表於2013-08-06

http://coolshell.cn/articles/1202.html

據說,這是Google的面試題。面試題目如下:

一共有25匹馬,有一個賽場,賽場有5個賽道,就是說最多同時可以有5匹馬一起比賽。假設每匹馬都跑的很穩定,不用任何其他工具,只通過馬與馬之間的比賽,試問,最少得比多少場才能知道跑得最快的5匹馬?(不能使用撞大運的演算法

很明顯這是一個演算法題,網上有很多貼子在討論這個問題,不過都沒有給出一個明確的答案。我想了想,想到下面的一個演算法:

1)分成5組A,B,C,D,E,比五場。然後根據每場結果分別給這五組內的五匹馬排序(從快到慢)。
2)每組的頭名再賽一場,取走第一名,然後該組第二名頂上。
3)重複第二步,直到選出前5名。

這個演算法是比較笨的演算法,總計需要賽10次,這個演算法應該是萬無一失的。現在的問題的就,如何優化這個演算法,想了想,的確是有優化的空間的。也就是說,是可以少於10次的。

 

想了一想,上面的那個演算法自從第6次開始就使用5個排序陣列的頭名做“冒泡法”,總是挑一個最優秀的出來,其實,在第6次以後除了挑出最優秀的,我們還可以在每次比賽後淘汰一些速度不行的,淘汰的馬匹數自然會比選出的更多,所以,一方面在找,另一方面在淘汰,找出前5名的速度應該會更快。

比如:我們假設比賽完第六場後,我們得到下面的排序:(每組排序是——快馬從左到右,各組頭名的排序是——快馬從上到下)

A組 A1 A2 A3 A4 A5
B組 B1 B2 B3 B4 B5
C組 C1 C2 C3 C4 C5
D組 D1 D2 D3 D4 D5
E組 E1 E2 E3 E4 E5

這樣,我們不但知道,A1是25匹馬裡最快的馬,而且我們可以淘汰近一半的馬,比如E2,E3,E4,E5就可以全部淘汰了,為什麼呢,因為比E2快的馬有A1,B1,C1,D1,E1這五匹馬,所以,E2後面的馬是無法進入前五名了;同理,D3和其後面的也進入不了前5;同理,C4,C5,B5都可以淘汰。

於是,在第六輪後我們可以得知,除了A1外的Top 4必然在下面這些馬中:

A組  A2 A3 A4 A5
B組 B1 B2 B3 B4 
C組 C1 C2 C3 
D組 D1 D2 
E組 E1

接下來的過程應該不必我多說了。重複前面的方法,儘可能淘汰無法進前N名的馬,於是後面的馬就越來越少,你所需要的比賽也會越來越少。

那麼,對於這個題,聰明的你知道最少要比賽幾場了嗎?

舉一反三,如果有64匹馬,8個賽道呢?不失一般性,如果有N匹馬,M個賽道呢?N = M*M,那麼公式是什麼呢?

期待你的答案!

(轉載本站文章請註明作者和出處 酷殼 – CoolShell.cn ,請勿用於任何商業用途)

———————————————————————————————————————

#43的解答:

好早聽說過這個題目,自習思考過方法,儘可能的讓每次賽馬後淘汰最多的馬(這個思想很好)
和樓主最初一樣,先分成5組,每組5匹,編號ABCDE,組內賽完後,共計五場
A1 B1 C1 D1 E1
A2 B2 C2 D2 E2
A3 B3 C3 D3 E3
A4 B4 C4 D4 E4
A5 B5 C5 D5 E5
第六場若取每組的第一比的話,最終可以淘汰4 + 3 + 2 + 1 = 10 (+ 1選出)
若取每組的第二比的話,最終可以淘汰4 + 4 + 4 + 2 = 14 (+ 1選出)
若取每組的第三比的話,最終可以淘汰3 + 3 + 3 + 3 = 12
… 後面肯定更少
所以第六場取每組第二比最佳,不妨設第六場順序為A2 > B2 > C2 > D2 > E2。
這樣第六場後剩餘的馬有10匹,只需選出前四即可
     B1 C1 D1 E1
A2 B2
A3 B3
A4
A5
第七場還是按照上面的原則,儘可能的淘汰最多的馬
選擇A3 B2 C1 D1 E1比賽,
若A3 B2為前兩名,那麼這四匹馬(前五)就找出了,為A2 A3 B1 B2,只用了7場
若A3為前兩名,B2不為前兩名,那麼就有三匹馬(前五)找出了A2 A3 (C1或D1或E1)淘汰B2 B3,最後就只剩五匹馬,所以只需要加賽一次,共計8場
若A3 B2都不為前兩名,A3 A4 A5 B2 B3都可以淘汰,最後A2 B1 C1 D1 E1賽一場就可以了。所以只需要8場。

綜合三種情況,最少需要8場

——————————————————————————————————————

第六輪使用最大值進行比較的後續具體解答:

前5次大家都一樣,排序後如下
A1,A2,A3,A4,A5
B1,B2,B3,B4,B5
C1,C2,C3,C4,C5
D1,D2,D3,D4,D5
E1,E2,E3,E4,E5
第六次,最大值比較,找出最快的馬

第7次參加比賽的馬匹為
A2 A3 B2 C2 D1
    (為什麼選這幾匹馬?相當於前面解答裡的選第二名)

下面就3種第7次可能的比賽結果進行分析: 
1、若第7次的比賽可能的一種結果為:
A2 A3 B2 C2 D1
此時必進入前5的是A1、A2、A3
可能進前5的是A4、A5、B1、B2、C1
則第8次為
A4、A5、B1、B2、C1
取前2名,與A1、A2、A3一起即為前5
2、若第7比賽結果為B2、A2、C2、A3、D1
此時必進入前5的是A1、B1、B2
可能進入前5的是A2、B3、B4、C1
第8次只要讓這4匹馬參賽就可以啦
3、若第7次比賽結果為D1、C2、A2、A3、B1
此時必進入前5的是A1、B1、C1、D1
而剩下的第5匹馬只可能出現在C2、D2、E1這3匹馬中,自然,讓這3匹馬參加第8次比賽就可以啦
總之,不管第7次的比賽結果如何,都在第8次比賽中做出適當的安排,即而可以在8次比賽後確定跑得最快的前5匹馬。

 

問題大致是這樣的:有36匹馬,通過賽馬尋找出最快的3匹。跑道可容納6匹馬同時賽跑,請問最快需要幾次賽馬可以找到最快的3匹馬?

    首先假設每匹馬的速度不一樣,這樣分析可以抓住要害。如果有速度相同的馬,則問題會稍微複雜一點,但基本思路是一致的。

    先給出一個最簡單的方案。36匹馬隨機分為6組,分別進行賽跑,那麼每組的後3名將被淘汰(這些馬不可能是最快的),餘下18匹馬。將剩餘的18匹馬再次 分為3組進行賽跑,餘下9匹。在最後9匹中隨機選擇6匹進行賽跑,將最快的3匹馬與剩下3匹馬進行賽跑,最後勝出的3匹馬即為所求。總共賽馬次數為 6+3+1+1=11

    讓我們回顧一下上述的賽馬過程。我們發現,最初的6次賽馬之後,剩餘的18匹馬實際上是區域性有序 的,每一組賽馬的3匹優勝馬都是有序的,很顯然上面的做法過於簡單,存在冗餘操作。我們接下來要做的工作實際上類似於歸併排序。那麼怎麼做可以用最少的賽馬次數從18匹馬中挑選出最快的3匹呢?

    答案是這樣的:將第一組中3匹優勝馬按排名令為A1,A2,A3,其中A1最快;同理第二組令為B1,B2,B3;第三組C1,C2,C3;以此類推,直 至F1,F2,F3。取A1,B1,C1,D1,E1,F1進行賽跑,為了方便說名,假設結果為 A1>B1>C1>D1>E1>F1。很顯然,D1,E1,F1,將被淘汰,於是D、E、F組的其餘馬也將被淘汰,因為他 們比這3匹馬還慢。再看C組,在剩餘有競爭力的9匹馬中(分別是A1,A2,A3,B1,B2,B3,C1,C2,C3),C1最多隻能排第三,那麼 C2,C3不可能成為最快的3匹馬之一,將其淘汰。同理觀察B組,可知B3也不具備成為前三甲的可能,淘汰之!現在只剩下 A1,A2,A3,B1,B2,C1共6匹馬,再次進行賽馬即得到答案。總共賽馬次數為6+1+1=8

    結論:最快通過8次賽馬可得答案。

相關文章