頭腦風暴(一) 三道面試題

序言:

昨天在酷殼看到三道面試題,發現對趣味性的題熱情依然不減啊,突然想起既然有博客了,何不建立一個由面試,趣味,腦筋急轉彎類題組成的專題呢~

頭腦風暴,給聰明人看的專題.

每篇文章題目均來自互聯網,會標明出處但解題思路絕不照搬.所以標均原創標籤了~


第一季 三道面試題:

在酷殼上看到的三道面試題,發現有兩道以前好像做過~最後一道還挺難,頓時來了興趣了 嗯~

酷殼: http://coolshell.cn

第一題 :

火車運煤問題

你是山西的一個煤老闆,你在礦區開採了有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歡迎指出,能完全證明我分析錯誤的請給我發私信討論 非常感謝^_^

終章~


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章