回 帖 发 新 帖 刷新版面

主题:[原创]爱因斯坦的思考题

/*爱因斯坦的思考题
在网上看到了个有趣的逻辑推理题,爱因斯坦声称世界上只有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;
}
         

回复列表 (共21个回复)

11 楼

[quote]这题没有答案...谁告诉你们有人养了金鱼....
爱因斯坦这道题根本就没有说过有人养了金鱼...[/quote]

没有说养鱼就是没有答案吗?

楼主都用程序把答案列出来,显然是根据逻辑推理得来的。

12 楼

我就是用人脑做出来的.

13 楼

推理出来很简单..不过我说德国人养的是鲸鱼是乌龟..是变色龙.这样都可以吧.题目并没有限定说是在那五种动物中选.
爱因斯坦曾经说过这样到题.
两个人从同一个烟囱爬出来 A很脏 B很干净那么哪个人会去洗澡
有人说是脏的人. 但是他说干净的人看到脏的人,马上跑去洗澡了
那又问是谁.有人说干净的人.
爱因斯坦又摇摇头说不是.因为这个前提不成立.
爱因斯坦说这道题并不是在说一道题还是说一种思维方法

14 楼

[quote]我也想景仰一下那个表^-^ 高中的时候愣是没画出来。

不过呢,话说回来,这个题给人脑来做还是相当难的,呵呵。

用计算机来穷举有点不厚道^-^[/quote]
恩~要是用人类的脑袋,恐怕有点难度!

15 楼


现在人聪明啊。哈哈

16 楼

支持一下

17 楼

这道题其实就是再考离散数学嘛.只要能静下心来好好分析的话就没那么看起来那么难了.

18 楼

总共15个条件
首先对这些条件按照确定性进行分类, 按照确定性由高到低排列判断顺序:
------------------------------------
A类条件 100%的确定条件共5个 
-直接条件----
1.挪威人住在第一个房子里面;
2.挪威人和住在蓝房子的人相邻;
3.住在中间那个房子里的人喝牛奶;
-间接条件----因为条件1 and 2 and "绿房子紧挨着白房子,在白房子的左边;",所以挪威人为黄色房子;
4.黄色房子里的人抽Dunhill牌香烟;
5.养马的人和抽Dunhill牌香烟的人相邻;
----------------------------------
B类条件,
6."绿房子紧挨着白房子,在白房子的左边;"
7."绿房子的主人喝咖啡;"
两个条件相关, 唯一组合,且按颜色进行假设有50%的正确率,为最优先判断的非确定性条件;
这两个条件确定后, 按颜色即可确定8."英国人住在红色的房子里;"
----------------------------------
C类条件
9.德国人抽Prince牌香烟;------与剩下的所有条件互不相容,所以优先考虑
10.丹麦人喝茶;11.抽BlueMaster牌香烟的人喝啤酒;----两者互不相容,同时考虑
12.瑞典人养狗作为宠物;13.抽Pall&nbsp;Mall牌香烟的人养鸟;----两者互不相容,   同时考虑
----------------------------------
D类条件
14.抽Blends牌香烟的人和养猫的人相邻;
15.抽Blends牌香烟的人和喝矿泉水的人相邻。
两个条件相关,内容为"或",最后再考虑.
----------------------------------
大家可以按照这个判断顺序来填表试试.

19 楼

10楼的同志问得好:
我看,是否真的有2%的人能算出来呢?
我本人是完全不懂的了。

20 楼

这题现在作为CSDN下的<<程序员杂志>>的有奖竞答题...

哈哈...
哪位可以去...

我来回复

您尚未登录,请登录后再回复。点此登录或注册