火車運煤
這個可能是乙個比較經典的智力題了,和以前的那個《賽馬問題》很相似,其題目如下:
你是山西的乙個煤老闆,你在礦區開採了有3000噸煤需要運送到市場上去賣,從你的礦區到市場有1000公里,你手裡有一列燒煤的火車,這個火車最多只能裝1000噸煤,且其能耗比較大——每一公里需要耗一噸煤。請問,作為乙個懂程式設計的煤老闆的你,你會怎麼運送才能運最多的煤到集市?
這道題一開始看上去好像是無解的,因為你的火車每一公里就要消耗一噸煤,而到目的地有1000公里,而火車最多只能裝1000噸媒。如果你的火車可以全部裝下,到目的地也會被全部燒光,一丁點也不剩。所以,很多人的第一反應都是覺得這個不太可能。
如果你一開始就覺得不太可能的話,這是很正常的。不過我不知道你還會不會繼續思考下去,如果你不想思考下去了,那麼我很為你擔憂,因為你可能並不是乙個不善於思考的人,而是乙個畏難的人,還有可能是乙個容易放棄的人。這對於你做好 乙個需要大量思考的工作的程式設計師來說可能並不適合。
我一開始也覺得不可能,後來想了一想,想到乙個解法可以最多運送500噸煤到市場,方法如下:(希望你先自己想一想再檢視這個答案)
裝1000噸煤,走250公里,扔下500噸煤,回礦山。
裝1000噸煤,走到250公里處,拿起250噸煤繼續向前到500公里處,扔下500噸煤,回礦山。此時火車上還有250噸,再加上在250公里處還有250噸煤,所以,火車是可以回礦山的。
裝上最後1000噸煤,走到500公里處,裝上那裡的500噸煤,然後一直走到目的。
於是,你最多可以運送500噸煤到市場(當然,火車也回不去了,因為那礦山沒有煤了)
賽馬問題:
一共有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,那麼公式是什麼呢?
火柴棍面試題:
有時候,有些面試題是很是無厘頭,這不,又有乙個,還記得小時候玩的的「火柴棍遊戲」嗎,就是移動一根火柴棍改變乙個圖或字的遊戲。程式面試居然也可以這麼玩,看看下面這個火柴棍式的程式面試題吧。
下面是乙個c程式,其想要輸出20個減號,不過,粗心的程式設計師把**寫錯了,你需要把下面的**修改正確,不過,你只能增加或是修改其中的乙個字元,請你給出三種答案。12
345int n = 20;
for(int i = 0; i < n; i--)
不要以為這題不是很難,我相信你並不那麼容易能找到3種方法。我覺得,如果你能在10分鐘內找出這三種方法,說明你真的很聰明,而且反應很快。當然,15分鐘內也不賴。不過,你要是30分鐘內找不到三種方法,當然,不說明你笨了,最多就是你的反應還不夠快。嘿嘿。就當是玩玩吧。
下面是我的答案:12
3456
78//第一種解法:在for迴圈中給n加乙個負號
for(int i = 0; i < -n; i--)
//第二種解法:把 n 初始化成 -20
int n = -20;
//第三種解法:把for迴圈中的 i 初始化成40
for(int i = 40; i < n; i--)
不過,我要告訴你,以上這些答案都不對(我就知道你會偷看答案的),不過,順著這些思路走很接近了。呵呵。
下面是正確答案——12
3456
78//第一種解法:在for迴圈中給 i 加乙個負號
for(int i = 0; -i < n; i--)
//第二種解法:在for迴圈中把 i-- 變成 n--
for(int i = 0; i < n; n--)
//第三種解法:把for迴圈中的 < 變成 +
for(int i = 0; i + n; i--)
其它相關的變種題如下:
通過修改、增加乙個字元,讓其輸出21個減號
通過修改、增加乙個字元,讓其只輸出1個減號
通過修改、增加乙個字元,讓其不輸出減號
(全文完)
附乙個有趣面試題
大家還記得前些天的那個火柴棍式的面試題嗎?很有趣吧。下面是我今天在stackexchange上看到的乙個有趣的面試題。大家不妨一起來思考一下。問題如下——
有兩個相同功能**如下,請在在a,b,c是什麼的情況下,請給出三個原因case 1比case 2快,還有三個原因case 2會比case 1要執行的快。(不考慮編譯器優化)
case 1123
45for (i=0; icase 2123
4567
89for (i=0; i我的第乙個反應是——
case1 要快一些,因為只有乙個i++的icase2如果要快的話,有乙個原因是,a, b, c其中乙個需要去先獲得乙個資源(比如乙個鎖),在case1下,每次都要去拿這個資源,而case2下,只需要拿一次然後。但這個可能是不對的,因為我無法想出乙個相同的語句塊放在case 1中會和放在case 2中有差別。(不過可能比較接近了)
繼續思考:這個題有點像是「同步和非同步」的問題,case 1是同步,case 2是非同步,所以,非同步快於同步,也許可以從這個方向出發,寫出a, b, c的語句塊。
不過,其要三個原因啊。各位,你們有想法嗎?
面試題 火車運煤問題
很有意思的東西 題目如下 你是山西的乙個煤老闆,你在礦區開採了有3000噸煤需要運送到市場上去賣,從你的礦區到市場有1000公里,你手裡有一列燒煤的火車,這個火車最多只能裝1000噸煤,且其能耗比較大 每一公里需要耗一噸煤。請問,作為乙個懂程式設計的煤老闆的你,你會怎麼運送才能運最多的煤到集市?這道...
面試題 火車運煤問題
面試題 火車運煤問題 你是山西的乙個煤老闆,你在礦區開採了有3000噸煤需要運送到市場上去賣,從你的礦區到市場有1000公里,你手裡有一列燒煤的火車,這個火車最多只能裝1000噸煤,且其能耗比較大 每一公里需要耗一噸煤。請問,作為乙個懂程式設計的煤老闆的你,你會怎麼運送才能運最多的煤到集市?答案一 ...
面試題 火車運煤問題
你是山西的乙個煤老闆,你在礦區開採了有3000噸煤需要運送到市場上去賣,從你的礦區到市場有1000公里,你手裡有一列燒煤的火車,這個火車最多只能裝1000噸煤,且其能耗比較大 每一公里需要耗一噸煤。請問,作為乙個懂程式設計的煤老闆的你,你會怎麼運送才能運最多的煤到集市?答案 於是,你最多可以運送50...