1. 程式人生 > >程式設計師經典智力面試題

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

一、火車運煤問題

你是山西的一個煤老闆,你在礦區開採了有3000噸煤需要運送到市場上去賣,從你的礦區到市場有1000公里,你手裡有一列燒煤的火車,這個火車最多隻能裝1000噸煤,且其能耗比較大——每一公里需要耗一噸煤。請問,作為一個懂程式設計的煤老闆的你,你會怎麼運送才能運最多的煤到集市?

答案:

  1. 裝1000噸煤,走250公里,扔下500噸煤,回礦山。
  2. 裝1000噸煤,走到250公里處,拿起250噸煤繼續向前到500公里處,扔下500噸煤,回礦山。此時火車上還有250噸,再加上在250公里處還有250噸煤,所以,火車是可以回礦山的。
  3. 裝上最後1000噸煤,走到500公里處,裝上那裡的500噸煤,然後一直走到目的。

於是,你最多可以運送500噸煤到市場(當然,火車也回不去了,因為那礦山沒有煤了)

533是應該是最優解,大家可以試下!

二、有兩個相同功能程式碼如下,請在在A,B,C是什麼的情況下,請給出三個原因case 1比case 2快,還有三個原因case 2會比case 1要執行的快。(不考慮編譯器優化)

case1

for (i=0; i<N; ++i){
    A;
    B;
    C;
}

case2

for (i=0; i<N; ++i){
    A;
}
for (i=0; i<N; ++i){
    B;
}
for (i=0; i<N; ++i){
    C;
}

我的第一個反應是——

  • case1 要快一些,因為只有一個i++的i<N的操作,而case 2卻有三個,這在點上,case 1就比case 2要快。
  • case2如果要快的話,有一個原因是,A, B, C其中一個需要去先獲得一個資源(比如一個鎖),在case1下,每次都要去拿這個資源,而case2下,只需要拿一次然後。但這個可能是不對的,因為我無法想出一個相同的語句塊放在case 1中會和放在case 2中有差別。(不過可能比較接近了)

繼續思考:這個題有點像是“同步和非同步”的問題,case 1是同步,case 2是非同步,所以,非同步快於同步,也許可以從這個方向出發,寫出A, B, C的語句塊。

不過,其要三個原因啊。各位,你們有想法嗎

發現又有一種情況,case 2要比case 1要快。比如,A, B, C分別訪問是不同的記憶體塊(陣列),那麼case 1就得在不同的記憶體塊上來回切換定址,而case2則可以連續地訪問記憶體塊。訪問連續的記憶體效率要高。尤其是三塊大記憶體。


三、“火柴棍式”程式設計師面試題

有時候,有些面試題是很是無厘頭,這不,又有一個,還記得小時候玩的的“火柴棍遊戲”嗎,就是移動一根火柴棍改變一個圖或字的遊戲。程式面試居然也可以這麼玩,看看下面這個火柴棍式的程式面試題吧。

下面是一個C程式,其想要輸出20個減號,不過,粗心的程式設計師把程式碼寫錯了,你需要把下面的程式碼修改正確,不過,你只能增加或是修改其中的一個字元,請你給出三種答案。

int n = 20;
for(int i = 0; i < n; i--){
    printf("-");
}

不要以為這題不是很難,我相信你並不那麼容易能找到3種方法。我覺得,如果你能在10分鐘內找出這三種方法,說明你真的很聰明,而且反應很快。當然,15分鐘內也不賴。不過,你要是30分鐘內找不到三種方法,當然,不說明你笨了,最多就是你的反應還不夠快。嘿嘿。就當是玩玩吧。

下面是我的答案

//第一種解法:在for迴圈中給n加一個負號
for(int i = 0; i < -n; i--)
//第二種解法:把 n 初始化成 -20
int n = -20;
//第三種解法:把for迴圈中的 i 初始化成40
for(int i = 40; i < n; i--)

不過,我要告訴你,以上這些答案都不對(我就知道你會偷看答案的),不過,順著這些思路走很接近了。呵呵。

下面是正確答案:

//第一種解法:在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個減號
  • 通過修改、增加一個字元,讓其不輸出減號