用程式解密愛因斯坦經典難題 C

2021-07-14 22:36:49 字數 3252 閱讀 5268

這個版本的程式我將不會使用任何推理,僅僅用程式描述這15個條件,然後窮舉所有組合得到滿足這15個條件的唯一解答。

首先構造「人」這個型別,根據題目可以知道每個人擁有顏色,香菸,飲料,寵物,位置,國籍這6個屬性。雖然在現實中,人抽香菸,喝飲料,養寵物,擁有國籍,只有這4個屬性,顏色和位置是房子的屬性,但是人住在哪間房子,就決定了這個人的顏色和位置,所以簡便起見,這6種屬性全部歸類到乙個抽象的「人」中。新建乙個person.h的檔案:

class person

;

根據這6種屬性,可以創造出5^6個不同的「人」。接著,觀察這15個條件,條件1,2,3,5,6,7,8,9,12,13,14,全部是以單個人作為約束條件,而剩下的4個都是以2個人之間的關係作為約束條件。首先可以把不滿足條件的人過濾掉,再通過組合判斷剩下的條件是否滿足。比如

1.英國人住紅色房子

,那麼國籍是英國但是顏色不是紅色的人就是不滿足條件的,反過來,顏色是紅色但是國籍不是英國的人也不滿足條件,用程式的描述就是:

bool test1(const person &p)

同理剩下的以人為約束的條件描述為:

bool test2(const person &p)

bool test3(const person &p)

bool test5(const person &p)

bool test6(const person &p)

bool test7(const person &p)

bool test8(const person &p)

bool test9(const person &p)

bool test12(const person &p)

bool test13(const person &p)

//條件14可直接表示為藍色房子是第二間房

bool test14(const person &p)

篩選出了有效的「人」,接著把這些「人」裝進不同的"房子"裡

vectorv1;

vectorv2;

vectorv3;

vectorv4;

vectorv5;

for(int color=0;color<5;++color)

for(int country=0;country<5;++country)

for(int drink=0;drink<5;++drink)

for(int cigarette=0;cigarette<5;++cigarette)

for(int pet=0;pet<5;++pet)

for(int index=1;index<=5;++index)}}

5個集合分別表示編號為1-5的5個房子,通過迴圈構建「人」,把符合條件的人扔到不同的房子裡去。這樣一來,得到了5個房子,每個房子裡都有一些人,這些人都是已經滿足了前面所有條件的,接著每個房子裡分別派出乙個人,判斷這5個人是否能滿足剩下的條件,如果滿足,那這5個人就是答案,不滿足,那就換人,直到所有的人都組合過就結束。

size_t s1=v1.size();

size_t s2=v2.size();

size_t s3=v3.size();

size_t s4=v4.size();

size_t s5=v5.size();

int count=0;

string countryname[5]=;

string colorname[5]=;

string drinkname[5]=;

string cigarettename[5]=;

string petname[5]=;

for(int i1=0;i1

去重的驗證,這裡用了一點小技巧:

bool testdistinct(person *pp)

; for(int i=0;i<5;++i) }

for(int i=0;i<25;i++)

return true;

}

人已經被分到不**子裡了,所以這5個人的index肯定是不會重複了,只需判斷剩下的5個屬性是否重複。每種屬性都是5個狀態,5種屬性就是25個狀態,然後用乙個長度為25的一維陣列來表示,比如state[0]表示藍色屬性的數量,state[1]表示綠色屬性的數量,state[5]表示喝茶人的數量,然後5個人迴圈判斷是否存在這些狀態,如果有那麼state陣列計數就加1。如果組合是不存在重複的,也就表示state陣列的每一項都正好是1,如果其中某一項不等於1,就表示一定存在重複。

剩下的4個條件判斷:

bool test4(person *pp)

return p1->index==p2->index-1;

}bool test10(person *pp)

return p1->index==p2->index-1||p1->index==p2->index+1;

}bool test11(person *pp)

return p1->index==p2->index-1||p1->index==p2->index+1;

}bool test15(person *pp)

return p1->index==p2->index-1||p1->index==p2->index+1;

}

原理就是從5個人中找到條件中的2個人,然後判斷他們的index屬性,所謂鄰居,隔壁都是表示他們的index是相連的。

到這裡**就已經寫完了,最後的計算結果是:

最後總結:為什麼有的問題人無法解決卻可以用計算機解決,雖然這個題目用畫**的方法推理出答案也不太難,但是相比較而言,電腦程式的思路更簡單粗暴,而人不可能用這種方式思考問題。假如你要計算987*512,而你並不會乘法口訣,你怎麼得到結果?這時給了你一張無比巨大的草稿紙,而且在上面的書寫速度會非常快,幸好你的加法還不錯,於是你不斷演算987+987=1974,1974+987=2961...至到加上512個987為止,最終你得到了正確答案,由於書寫速度非常快,甚至快過你用乘法口訣得出答案,這就是計算機解決人無法解決問題的原理,計算機就好比這樣的草稿紙。至於如何把問題描述給計算機計算(把乘法問題轉成加法問題),以及讓計算機執行得更快(你可以累加512次,你也可以僅僅累加9次),這就涉及到電腦科學的一門重要課程--資料結構與演算法。

愛因斯坦難題

愛因斯坦在20世紀初的這個問題,據說世界上有98 的人回答不出來 問題 在一條街上,有5座房子,噴了5中顏色。沒個房子住著不同國籍的人。每個人喝不同的飲料,抽不同品牌的香菸,養不同的寵物。問題是 誰養魚?2.瑞典人養狗 3.丹麥人喝茶 4.綠色房子在白色房子左邊 5.綠房子主人喝咖啡 6.抽pall...

愛因斯坦火車

今天下班時候很疲勞,就決定路上換換口味,看看物理緩解下,同時想為封建迷信找點理論基礎,於是瞄上了號稱 測不准 的量子物理,無奈上學學的都還給老師了,只能從頭開始,於是先簡單的學了學狹義相對論。下面分享一下。簡單來說就是有一輛火車,在火車中間位置有個光源,以火車為參照物的話,相對於火車,光是同時到達火...

愛因斯坦的悼詞

朱也曠 對於現代物理學,1905年是個有點特殊的年份。在這年9月的德國 物理學年鑑 annalen der physik 上,發表了由一位默默無聞的專利審查員愛因斯坦所寫的三篇 三篇 中的任何一篇,都足以使作者享有大物理學家的盛名。而其中最有名的便是 論動體的電動力學 此文宣告了相對論的誕生。在科學...