序言:
昨天在酷殼看到三道面試題,發現對趣味性的題熱情依然不減啊,突然想起既然有博客了,何不建立一個由面試,趣味,腦筋急轉彎類題組成的專題呢~
頭腦風暴,給聰明人看的專題.
每篇文章題目均來自互聯網,會標明出處但解題思路絕不照搬.所以標均原創標籤了~
第一季 三道面試題:
在酷殼上看到的三道面試題,發現有兩道以前好像做過~最後一道還挺難,頓時來了興趣了 嗯~
第一題 :
火車運煤問題
你是山西的一個煤老闆,你在礦區開採了有3000噸煤需要運送到市場上去賣,從你的礦區到市場有1000公里,你手裏有一列燒煤的火車,這個火車最多隻能裝1000噸煤,且其能耗比較大——每一公里需要耗一噸煤。請問,作爲一個懂編程的煤老闆的你,你會怎麼運送才能運最多的煤到集市?一道經典的貪心思想題目 分析:
1.首先直接運送肯定是不行的,必然要分次運,那麼問題就在於運到那個點最合適.
2.既然要求煤的消耗最小,那麼必須求出主要的消耗點,以減少消耗,假設第一次先運到點N,那麼3000噸要往返5次,若需要求最小消耗,必須減少往返.則一個子問題爲,運送過程消耗多少噸煤可以減少往返? 答案是1000噸,當煤爲2000時,往返爲3次.
3.結果很容易就出來了,題目可以化簡爲,每消耗1000噸煤,能走的最遠距離,當煤剩1000噸時,減去剩餘距離,爲最終結果.
4.擴展:此題可以擴展爲若能裝X噸煤的火車和X公里路,共有M*X噸煤,問能最後剩多少?
直接將思想轉化爲程序 源代碼:
#include <myhead.h>
class Brainstorming1_1
{
public:
Brainstorming1_1()
: x(X),l(X),m(M) { }
Brainstorming1_1(int _x,int _m)
: x(_x),l(_x),m(_m) { }
void setResult() {
puts("*********************************************************");
printf("x=%d,m=%d\n",x,m);
if(m<=1) { //必須重新構造後使用
puts("NO!");
return ;
}
while(m-1) { //當m=1時僅剩X,一次全運完
puts("--------------------------------------");
int ll=2*m-1; //所需走的次數
printf("ll=%d\n",ll);
int n=x/ll; //每消耗X所走的走的最大路程
printf("n=%d\n",n);
l-=n; //剩餘路程
printf("l=%d\n",l);
-- m;
}
puts("Result:");
printf("%d\n",x-l);
}
private:
enum {
X=1000, //裝載量和路程
M=3 //總量的係數
};
int x,l,m;
};
int main()
{
Brainstorming1_1 brtg;
brtg.setResult();
brtg=Brainstorming1_1(1000,5);
brtg.setResult();
return 0;
}
程序有個小BUG 當最後剩餘路程小於X噸煤能走的距離時會不準確.歡迎大家留言完善.
第二題:
“火柴棍式”程序員面試題
下面是一個C程序,其想要輸出20個減號,不過,粗心的程序員把代碼寫錯了,你需要把下面的代碼修改正確,不過,你只能增加或是修改其中的一個字符,請你給出三種答案.
int n = 20;
for(int i = 0; i < n; i--){
printf("-");
}
不要以爲這題不是很難,我相信你並不那麼容易能找到3種方法。我覺得,如果你能在10分鐘內找出這三種方法,說明你真的很聰明,而且反應很快。當然,15分鐘內也不賴。不過,你要是30分鐘內找不到三種方法,當然,不說明你笨了,最多就是你的反應還不夠快。嘿嘿。就當是玩玩吧。
這道題沒什麼分析的,就是給酷殼宣傳一下~
第三題:
賽馬問題
據說,這是Google的面試題。面試題目如下:
一共有25匹馬,有一個賽場,賽場有5個賽道,就是說最多同時可以有5匹馬一起比賽。假設每匹馬都跑的很穩定,不用任何其他工具,只通過馬與馬之間的比賽,試問,最少得比多少場才能知道跑得最快的5匹馬?(不能使用撞大運的算法)
我感覺思想來說算動態規劃吧~ 分析:
1.首先肯定是要每批馬比一次,這需要五次.此時爲5個排好的序列,我們由此可得到一個矩陣:
a1,a2,a3,a4,a5
b1,b2,b3,b4,b5
c1,c2,c3,c4,c5
d1,d2,d3,d4,d5
接下來還得繼續排序~行已經排完了問題在於應該對於哪一列排序呢?
1.首先是樸素方法,對第一列排序,每次能求出最大的,最大的那行第二位加入繼續跑,結果爲10次,不過這當然不是我們想要的結果.
2.以一的思想爲基礎,通過觀察發現,本列排序後,可以求出本列這匹馬以及後面馬的最前次序.大於10刪除.
例如以第二排排序,每匹馬可能的最前次序爲:
1,2,3,4,5
1,4,5,6,7
1,6,6,7,8
1,8,9,0,0
1,0,0,0,0
以第三排排序:
1,2,3,4,5
1,2,6,7,8
1,2,9,0,0
1,2,0,0,0
1,2,0,0,0
第四排省略~根據矩陣可見,對於每個排列順序,某些馬匹因爲其可能的最前位置大於5,就可以刪除了.並且可知,當對第二排排序時,已知的順序最多,可以淘汰的也最多.經過淘汰後,我們得到下面這樣的矩陣.
1,2,3,4,5 a1,a2,a3,a4,a5
1,4,5 b1,b2,b3
1 c1
1 d1
1 e1
此時以排6次,對所有1,2和3的數排序可以再3次內求出,這樣結果爲9次,但是忙了這麼半天才省了一次?那這文章白寫了~
因爲b1,c1,d1,e1的情況都不知道,所以a2這第二的位置不一定能坐得住~所以對這五個數排序~若a2不是第一位,情況很好~當前面有一個數的情況,則可以刪除b3,a5,e1. 剩五個,得8次,多個情況下以此類推.
若a2是第一位,看b1是不是第一位,b1是第一位~則需9場,以爲b2可能依然大於剩下的,b1不是第一位,刪除b3,將b2,a3,a4,a5和餘下的兩個比較即可,好像也需要9次
看來真的是9次,很鬱悶~~~
分析的可能有點BUG歡迎指出,能完全證明我分析錯誤的請給我發私信討論 非常感謝^_^
終章~