犹豫 发表于 2008-12-10 09:57:44

C#轻松解决世纪迷题:爱因斯坦算法

<br>  <b>下面的问题相信很多人都听过:</b><br>  1 有五栋五种颜色的房子 <br>  2 每一位房子的主人国籍都不同 <br>  3 这五个人每人只喝一种饮料,只抽一种牌子的香烟,只养一种宠物 <br>  4 没有人有相同的宠物,抽相同牌子的香烟,喝相同的饮料<br>  <b>提示:</b><br>  1、 英国人住在红房子里 <br>  2 、瑞典人养了一条狗 <br>  3 、丹麦人喝茶 <br>  4 、绿房子在白房子左边 <br>  5 、绿房子主人喝咖啡 <br>  6 、抽PALL MALL烟的人养了一只鸟 <br>  7 、黄房子主人抽DUNHILL烟 <br>  8 、住在中间那间房子的人喝牛奶 <br>  9 、挪威人住第一间房子 <br>  10 、抽混合烟的人住在养鱼人的旁边 <br>  11 、养马人住在DUNHILL烟的人旁边 <br>  12 、抽BLUE MASTER烟的人喝啤酒 <br>  13、 德国人抽PRINCE烟 <br>  14 、挪威人住在蓝房子旁边 <br>  15 、抽混合烟的人的邻居喝矿泉水<br>  <b>问题是: 谁养鱼?</b><br>  这道迷题出自1981年柏林的德国逻辑思考学院。据说世界上只有2%的人能出答案。就连大名鼎鼎的爱因斯坦也成为此题大伤脑筋,所以这道题也经常被国内外知名公司用做面试题目,相信许多朋友都只做出过一个答案,如果碰巧你属于那98%该怎么办呢。没关系,如果这个问题用电脑来解决就非常easy了。<br>  程序代码如下:<br>  using System;<br>  namespace netsafe.math<br>  {<br>  public class ayst<br>   {<br>   /// <summary><br>   /// 问题中的所有元素<br>   /// </summary><br>   string[,] data= {{"黄房子", "蓝房子", "白房子", "红房子", "绿房子"},<br>      {"挪威人", "英国人", "德国人", "丹麦人", "瑞典人"},<br>      {"DUNHILL", "PRINCE", "混合烟", "PALL MALL", "BLUE MASTER"},<br>      {"咖 啡", "矿泉水", "茶", "牛奶", " 啤酒 "},<br>      {"鱼", " 恐龙", "马", "鸟", "狗"}};<br>  <br>   /// <summary><br>   /// answer用来存放答案<br>   /// </summary><br>   int[,] answer=new int;<br>  int[,] ALL=new int;<br>   int count=1;<br>   int nLevel = 0;<br>   int[] List=new int;<br>   public static void Main(string[] args)<br>   {<br>    ayst c=new ayst();<br>    c.p(); ///生成全排列到all<br>    c.run();<br>    Console.Read(); /// 按任意键继续<br>  }<br>   void run()<br>   {<br>    int i1,i2,i3,i4,i5;<br>    ///通过逻辑条件顺序的有效选择来优化程序<br>    for (i1=1;i1<=120;i1)  ///房子<br>    {<br>    /// 9 、挪威人住第一间房子<br>    /// 14 、挪威人住在蓝房子旁边<br>    /// 不满足条件就短路<br>    ///<br>  if (ALL!=2)continue;<br>    for(int j=0;j<5;j,answer=ALL);<br>    for (i2=1;i2<=120;i2)  ///人种<br>    {  <br>     for(int j=0;j<5;j,answer=ALL);<br>     /// 9 、挪威人住第一间房子<br>     if (ALL!=1)continue;<br>     ///1、 英国人住在红房子里 <br>     ///<br>     if (find(1,4)!=find(2,2))continue;<br>  /// 4 、绿房子在白房子左边 <br>     /// <br>     if (find(1,5)>find(1,3))continue;<br>     for (i3=1;i3<=120;i3)   ///烟<br>     {<br>     <br>     for(int j=0;j<5;j,answer=ALL);<br>     /// 13、 德国人抽PRINCE烟 <br>     /// <br>     if(find(2,3)!=find(3,2))continue;<br>     /// 7 、黄房子主人抽DUNHILL烟<br>     /// <br>     if(find(1,1)!=find(3,1))continue;<br>     for (i4=1;i4<=120;i4)  ///饮料<br>     { <br>      <br>      for(int j=0;j<5;j,answer=ALL);<br>      /// 8 、住在中间那间房子的人喝牛奶<br>      /// <br>      if(ALL!=4)continue;<br>  /// 5 、绿房子主人喝咖啡 <br>      /// <br>      if (find(1,5)!=find(4,1))continue;<br>  /// 3 、丹麦人喝茶 <br>      /// <br>      if(find(2,4)!=find(4,3))continue;<br>  /// 15 、抽混合烟的人的邻居喝矿泉水 <br>      <br>      if(Math.Abs(find(3,3)-find(4,2))!=1)continue;<br>      /// 12 、抽BLUE MASTER烟的人喝啤酒<br>      ///<br>  if(find(3,5)!=find(4,5))continue;<br>  for (i5=1;i5<=120;i5)  ///宠物<br>      {   <br>      <br>      for(int j=0;j<5;j,answer=ALL);<br>      /// 10 、抽混合烟的人住在养鱼人的旁边<br>      /// <br>      if(Math.Abs(find(3,3)-find(5,1))!=1)continue;<br>  /// 2 、瑞典人养了一条狗 <br>      /// <br>      if(find(2,5)!=find(5,5))continue;<br>      /// 6 、抽PALL MALL烟的人养了一只鸟 <br>      /// <br>      if(find(3,4)!=find(5,4))continue;<br>      /// 11 、养马人住在DUNHILL烟的人旁边 <br>      ///<br>  if(Math.Abs(find(5,3)-find(3,1))!=1)continue;<br>      ///<br>      ///能活到这里的data,当然是答案喽<br>      ///<br>      write_answer();<br>   <br>      }<br>   <br>     }<br>     }<br>   <br>    }<br>    }<br>   }<br>  /// <summary><br>   /// 非常典型的用递归实现排列组合算法。<br>   /// </summary><br>   public void p()  <br>   {<br>    int nCount,nJudge,key;<br>    nLevel;<br>    if(nLevel>5)<br>    {<br>    writeall();///有一种排列就写到All数组里<br>    nLevel--;<br>    return;<br>    }<br>  for(nCount=1;nCount<=5;nCount)<br>    {<br>    key=0;<br>    for(nJudge=0;nJudge<=nLevel-1;nJudge)<br>     if(nCount==List)<br>     {<br>     key=1;<br>     break;<br>     }<br>   <br>    if(key==0)<br>    {<br>     List=nCount;<br>     p();<br>    }<br>    }<br>    nLevel--;<br>   }<br>  /// <summary><br>   /// 写入all数组<br>   /// </summary><br>  void writeall()<br>   {<br>    int i;<br>    for (i=1;i<=5;i)<br>    {<br>    ALL=List;<br>    } <br>    count;<br>   }<br>  int find(int i,int j)<br>   {<br>  int k;<br>    for(k=0;k<=5;k)<br>    {<br>    if (answer==j)<br>    {<br>     return k;<br>    }<br>    }<br>    return -1;<br>   }<br>  /// <summary><br>   /// 将答案打印出来<br>   /// </summary><br>   void write_answer()<br>   {<br>    <br>    for (int i = 1;i<=5;i)<br>    {<br>    for(int j=1 ;j<=5;j)<br>    {<br>     Console.Write(data-1] ",");<br>  }<br>    Console.WriteLine();<br>    }<br>    Console.WriteLine();<br>   }<br>   }<br>  }<br>  说明:程序使用C#,在Microsoft Visual Studio.net下编译执行通过。如果你没有Microsoft Visual C# 需要安装Microsoft(r) .NET Framework SDK ,把上述代码保存到ayst.cs,然后在命令行模式下执行csc ayst.cs ,然后执行ayst.exe也可以。这个程序是很久之前写的。当时只是为了得到答案,所以程序写的比较乱。让同行见笑了。以下是程序的运行结果(答案一总7种,没想到吧):<br>  黄房子,蓝房子,红房子,绿房子,白房子,<br>  挪威人,丹麦人,英国人,德国人,瑞典人,<br>  DUNHILL,混合烟,PALL MALL,PRINCE,BLUE  MASTER,<br>  矿泉水,茶,牛奶,咖 啡, 啤酒 ,<br>  鱼,马,鸟, 恐龙,狗,<br>  绿房子,蓝房子,黄房子,红房子,白房子,<br>  挪威人,德国人,瑞典人,英国人,丹麦人,<br>  混合烟,PRINCE,DUNHILL,BLUE   MASTER,PALL MALL,<br>  咖 啡,矿泉水,牛奶, 啤酒 ,茶,<br>   恐龙,鱼,狗,马,鸟,<br>  绿房子,蓝房子,白房子,黄房子,红房子,<br>  挪威人,德国人,瑞典人,丹麦人,英国人,<br>  PALL MALL,PRINCE,混合烟,DUNHILL,BLUE  MASTER,<br>  咖 啡,矿泉水,牛奶,茶, 啤酒 ,<br>  鸟,鱼,狗, 恐龙,马,<br>  绿房子,蓝房子,白房子,黄房子,红房子,<br>  挪威人,德国人,瑞典人,丹麦人,英国人,<br>  PALL MALL,PRINCE,混合烟,DUNHILL,BLUE  MASTER,<br>  咖 啡,矿泉水,牛奶,茶, 啤酒 ,<br>  鸟, 恐龙,狗,鱼,马,<br>  绿房子,蓝房子,白房子,红房子,黄房子,<br>  挪威人,德国人,瑞典人,英国人,丹麦人,<br>  PALL MALL,PRINCE,混合烟,BLUE  MASTER,DUNHILL,<br>  咖 啡,矿泉水,牛奶, 啤酒 ,茶,<br>  鸟,鱼,狗,马, 恐龙,<br>  绿房子,蓝房子,红房子,黄房子,白房子,<br>  挪威人,德国人,英国人,丹麦人,瑞典人,<br>  PALL MALL,PRINCE,混合烟,DUNHILL,BLUE  MASTER,<br>  咖 啡,矿泉水,牛奶,茶, 啤酒 ,<br>  鸟,鱼,马, 恐龙,狗,<br>  绿房子,蓝房子,红房子,黄房子,白房子,<br>  挪威人,德国人,英国人,丹麦人,瑞典人,<br>  PALL MALL,PRINCE,混合烟,DUNHILL,BLUE  MASTER,<br>  咖 啡,矿泉水,牛奶,茶, 啤酒 ,<br>  鸟, 恐龙,马, <
页: [1]
查看完整版本: C#轻松解决世纪迷题:爱因斯坦算法