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

Posted on 2006-12-06 22:31 梦想飞扬 阅读(2946) 评论(18)  编辑 收藏 引用

Feedback

# re: 爱因斯坦的思考题  回复  更多评论   

2006-12-08 15:13 by skinny_
"抽Pall Mall牌香烟的人养鸟"
看看你的答案,有养鸟的人么?

我的印象里,这似乎是个无解的题目,因为缺少条件,还少了一个人,你的答案也证明了这一点,有两个人养鱼

# re: 爱因斯坦的思考题  回复  更多评论   

2006-12-08 22:45 by 梦想飞扬
呵呵,我开始确实大意了
但如果第一次碰到合适的答案就输出的话,也可以找到一个答案的.
为了不误人子弟,代码我已经改过来了.

# re: 爱因斯坦的思考题  回复  更多评论   

2006-12-10 16:31 by 曦恝恝
收藏了 !

# re: 爱因斯坦的思考题  回复  更多评论   

2006-12-10 16:41 by 曦恝恝
收藏了 !1


# re: 爱因斯坦的思考题  回复  更多评论   

2007-03-20 20:04 by pengkuny
确实很精彩,尤其是"{//把满足条件的序号填入结构数组"这一段,
加上前面
House[0].nation = "挪威";//挪威人住在第一个房子里面
House[1].color = "蓝色";//挪威人和住在蓝房子的人相邻,即蓝房子是第2个房子
House[2].drink = "牛奶";// 住在中间那个房子里的人喝牛奶
总共25个完美的信息.

# re: 爱因斯坦的思考题  回复  更多评论   

2007-06-18 09:25 by 倔强超人
恩 ,跟智商无关

推理 ,可能会麻烦点

总有出口的

# re: 爱因斯坦的思考题  回复  更多评论   

2007-08-10 13:32 by
德国人养鱼

# re: 爱因斯坦的思考题  回复  更多评论   

2007-10-21 15:51 by 没有
我也做出来了,花了75分钟.
利用推理过程算出来的```

# re: 爱因斯坦的思考题  回复  更多评论   

2007-10-21 17:39 by Minidx全文检索
厉害!

# re: 爱因斯坦的思考题  回复  更多评论   

2007-12-25 15:49 by 秦歌
这样呀!厉害!

# re: 爱因斯坦的思考题  回复  更多评论   

2008-12-17 09:59 by 桀达
呵呵这到题目高一的时候做过,花了83分钟

# re: 爱因斯坦的思考题  回复  更多评论   

2008-12-28 09:21 by 黄色
花了83分钟

# re: 爱因斯坦的思考题[未登录]  回复  更多评论   

2009-05-11 16:45 by 123
是,跟智商无关

# re: 爱因斯坦的思考题  回复  更多评论   

2009-09-08 05:34 by 啦啦啦
1号房 2号房 3号房 4号房 5号房
黄色 蓝色 红色 绿色 白色
挪威 丹麦 英国 德国 瑞典
矿泉水 茶 牛奶 咖啡 啤酒
Dun. Ble. Pal. Pri. Blu.
猫 马 鸟 鱼 狗

# re: 爱因斯坦的思考题  回复  更多评论   

2009-12-25 01:24 by 黄色
黄色 蓝色 红色 绿色 白色

#  爱因斯坦的思考题  回复  更多评论   

2011-04-23 16:22 by 祁韵好
看来我的智商还挺不错的,才上小四花了40分钟就作出来了。

# re: 爱因斯坦的思考题  回复  更多评论   

2012-06-24 21:59 by
我用了35分钟

# re: 爱因斯坦的思考题  回复  更多评论   

2012-06-24 21:59 by
你好自恋

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理