/*愛因斯坦的思考題
在網上看到了個有趣的邏輯推理題,愛因斯坦聲稱世界上只有2%的人能解出:
有五個具有五種不同顏色的房間排成一排;
每個房間里分別住著一個不同國籍的人;
每個人都在喝一種特定品牌的飲料,抽一特定品牌的煙,養一特定的寵物;
沒有任意兩個人在抽相同品牌的香煙,或喝相同品牌的飲料,或養相同的寵物。
問題:誰在養魚作為寵物?
愛因斯坦給出如下線索:
英國人住在紅色的房子里;
瑞典人養狗作為寵物;
丹麥人喝茶;
綠房子緊挨著白房子,在白房子的左邊;
綠房子的主人喝咖啡;
抽Pall Mall牌香煙的人養鳥;
黃色房子里的人抽Dunhill牌香煙;
住在中間那個房子里的人喝牛奶;
挪威人住在第一個房子里面;
抽Blends牌香煙的人和養貓的人相鄰;
養馬的人和抽Dunhill牌香煙的人相鄰;
抽BlueMaster牌香煙的人喝啤酒;
德國人抽Prince牌香煙;
挪威人和住在藍房子的人相鄰;
抽Blends牌香煙的人和喝礦泉水的人相鄰。
國家 房子 寵物 飲料 香煙
挪威 黃色 貓 礦泉水 Dunhill
丹麥 藍色 馬 茶 Blends
英國 紅色 鳥 牛奶 PallMall
德國 綠色 魚 咖啡 Prince
瑞典 白色 狗 啤酒 BlueMaster
*/
/*
算法思路:
以房子的位置為主序,把國籍,顏色,寵物,飲料,香煙都作為該房子的一個成員,每一個成員都有可能
處在任何位置,為所有成員窮舉每一個位置,再根據已知條件進行適當剪枝,找到唯一的解
*/
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main(void)
{
string Title[5] = {"國籍","顏色","寵物","飲料","香煙"};
struct {
string nation;
string color;
string pet;
string drink;
string cigarette;
} House[5];//房子從左到右編號
House[0].nation = "挪威";//挪威人住在第一個房子里面
House[1].color = "藍色";//挪威人和住在藍房子的人相鄰,即藍房子是第2個房子
House[2].drink = "牛奶";// 住在中間那個房子里的人喝牛奶
for (int e=1; e<5; e++) //表示英國人的房子序號
for (int r=1; r<5; r++)//表示瑞典人的房子序號
for (int d=1; d<5; d++)//表示丹麥人的房子序號
for (int g=0; g<5; g++)//表示綠房子的序號
for (int p=0; p<5; p++)//表示抽Pall Mall牌香煙的人的房子序號
for (int y=0; y<5; y++)//表示黃色房子的序號
for (int b=0; b<5; b++)//表示喝啤酒人的房子序號
for (int h=0; h<5; h++)//表示養馬的人的房子序號
for (int cat=0; cat<5; cat++)//表示養貓的人的房子序號
{
int Germany = 10 - 0 - e - r - d; //表示德國人的房子序號,德國人抽Prince牌香煙;
int Blends = 10 - p - y - b - Germany;//表示抽Blends牌香煙的人的房子序號
int white = 10 - 1 - e - g - y; //表示白房子的序號
int water = 10 - 2 - d - g - b; //表示喝礦泉水的人的房子序號
int fish = 10 - r - p - h - cat;//表示養魚的人的房子序號
bool A1 = (e!=1); //英國人住在紅色的房子里;根據房子和國家判斷
bool A2 = (r!=e); //瑞典人養狗作為寵物;根據國家和寵物判斷
bool A3 = (d!=e && d!=r && d!=2);//丹麥人喝茶;根據國家和飲料判斷
bool A4 = (g!=1 && g!=2 && g!=e && g!=d);//綠房子的主人喝咖啡;根據顏色和飲料判斷
bool A5 = (p!=r); //抽Pall Mall牌香煙的人養鳥;根據香煙和寵物判斷
bool A6 = (y!=e && y!=1 && y!=g && y!=p);//黃色房子里的人抽Dunhill牌香煙;根據顏色和香煙判斷
bool A7 = (b!=2 && b!=d && b!=g && b!=p && b!=y);//抽BlueMaster牌香煙的人喝啤酒;根據香煙和飲料判斷
bool A8 = (h!=r && h!=p && (h==y+1 || h==y-1));//養馬的人和抽Dunhill牌香煙的人相鄰,根據香煙和寵物判斷
bool A9 = (white == g + 1); //綠房子緊挨著白房子,在白房子的左邊;
bool A0 = (cat==Blends-1 || cat==Blends+1);//Blends牌香煙的人和養貓的人相鄰;
bool A11 = (water==Blends-1 || water==Blends+1);//抽Blends牌香煙的人和喝礦泉水的人相鄰
if (A1 && A2 && A3 && A4 && A5 && A6 && A7 && A8 && A9 && A0 && A11)
{//把滿足條件的序號填入結構數組
House[e].nation = "英國";
House[e].color = "紅色";
House[r].nation = "瑞典";
House[r].pet = "狗";
House[d].nation = "丹麥";
House[d].drink = "茶";
House[g].color = "綠色";
House[g].drink = "咖啡";
House[p].cigarette = "Pall Mall";
House[p].pet = "鳥";
House[y].color = "黃色";
House[y].cigarette = "Dunhill";
House[b].cigarette = "BlueMaster";
House[b].drink = "啤酒";
House[h].pet = "馬";
House[Germany].nation = "德國";
House[Germany].cigarette = "Prince";
House[Blends].cigarette = "Blends";
House[white].color = "白色";
House[water].drink = "礦泉水";
House[cat].pet = "貓";
House[fish].pet = "魚";
goto end;
}
}
end:
for (int i=0; i<5; i++)
cout << Title[i] << "\t";
cout << endl << endl;
for (int i=0; i<5; i++)
{
cout << House[i].nation << "\t";
cout << House[i].color << "\t";
cout << House[i].pet << "\t";
cout << House[i].drink << "\t";
cout << House[i].cigarette << "\t";
cout << endl;
}
//輸出到文件
ofstream out("愛因斯坦的思考題.txt");
for (int i=0; i<5; i++)
out << Title[i] << "\t";
out << endl << endl;
for (int i=0; i<5; i++)
{
out << House[i].nation << "\t";
out << House[i].color << "\t";
out << House[i].pet << "\t";
out << House[i].drink << "\t";
out << House[i].cigarette << "\t";
out << endl;
}
out.close();
system("pause");
return 0;
}