C#轻松解决世纪迷题

类别:.NET开发 点击:0 评论:0 推荐:

作者:李志勇 发表于赛迪网。

e-mail: [email protected]

转载请注明出处。


下面的问题相信很多人都听过:
1 有五栋五种颜色的房子
2 每一位房子的主人国籍都不同
3 这五个人每人只喝一种饮料,只抽一种牌子的香烟,只养一种宠物
4 没有人有相同的宠物,抽相同牌子的香烟,喝相同的饮料

提示:

1、 英国人住在红房子里
2 、瑞典人养了一条狗
3 、丹麦人喝茶
4 、绿房子在白房子左边
5 、绿房子主人喝咖啡
6 、抽PALL MALL烟的人养了一只鸟
7 、黄房子主人抽DUNHILL烟
8 、住在中间那间房子的人喝牛奶
9 、挪威人住第一间房子
10 、抽混合烟的人住在养鱼人的旁边
11 、养马人住在DUNHILL烟的人旁边
12 、抽BLUE MASTER烟的人喝啤酒
13、 德国人抽PRINCE烟
14 、挪威人住在蓝房子旁边
15 、抽混合烟的人的邻居喝矿泉水

问题是: 谁养鱼?
这道迷题出自1981年柏林的德国逻辑思考学院。据说世界上只有2%的人能出答案。就连大名鼎鼎的爱因斯坦也成为此题大伤脑筋,所以这道题也经常被国内外知名公司用做面试题目,相信许多朋友都只做出过一个答案,如果碰巧你属于那98%该怎么办呢。没关系,如果这个问题用电脑来解决就非常easy了。
程序代码如下:
using System;

namespace netsafe.math
{

 public class ayst
 {

  
  /// <summary>
  /// 问题中的所有元素
  /// </summary>
  string[,] data= {{"黄房子", "蓝房子", "白房子", "红房子", "绿房子"},
       {"挪威人", "英国人", "德国人", "丹麦人", "瑞典人"},
       {"DUNHILL", "PRINCE", "混合烟", "PALL MALL", "BLUE MASTER"},
       {"咖 啡", "矿泉水", "茶", "牛奶", " 啤酒 "},
       {"鱼", " 恐龙", "马", "鸟", "狗"}};


  /// <summary>
  /// answer用来存放答案
  /// </summary>
  int[,] answer=new int[6, 6];

  int[,] ALL=new int[6,122];
  int count=1;
  int nLevel = 0;
  int[] List=new int[6];
  public static void Main(string[] args)
  {
   ayst c=new ayst();
   c.p();  ///生成全排列到all
   c.run();
   Console.Read(); /// 按任意键继续

  }
  void run()
  {
   int i1,i2,i3,i4,i5;
   ///通过逻辑条件顺序的有效选择来优化程序
   for (i1=1;i1<=120;i1++)    ///房子
   {
    /// 9 、挪威人住第一间房子
    /// 14 、挪威人住在蓝房子旁边
    /// 不满足条件就短路
    /// 

    if (ALL[2,i1]!=2)continue;


    for(int j=0;j<5;j++,answer[j,1]=ALL[j,i1]);
    for (i2=1;i2<=120;i2++)   ///人种
    {   
  
     for(int j=0;j<5;j++,answer[j,2]=ALL[j,i2]);
     /// 9 、挪威人住第一间房子
     if (ALL[1,i2]!=1)continue;
     ///1、 英国人住在红房子里
     ///
     if (find(1,4)!=find(2,2))continue;

     /// 4 、绿房子在白房子左边
     /// 
     if (find(1,5)>find(1,3))continue;


     for (i3=1;i3<=120;i3++)     ///烟
     {
     
      for(int j=0;j<5;j++,answer[j,3]=ALL[j,i3]);
      ///  13、 德国人抽PRINCE烟
      ///  
      if(find(2,3)!=find(3,2))continue;
      ///  7 、黄房子主人抽DUNHILL烟
      ///  
      if(find(1,1)!=find(3,1))continue;


      for (i4=1;i4<=120;i4++)   ///饮料
      { 
       
       for(int j=0;j<5;j++,answer[j,4]=ALL[j,i4]);
       ///  8 、住在中间那间房子的人喝牛奶
       ///  
       if(ALL[3,i4]!=4)continue;

       /// 5 、绿房子主人喝咖啡
       /// 
       if (find(1,5)!=find(4,1))continue;

       ///  3 、丹麦人喝茶
       ///  
       if(find(2,4)!=find(4,3))continue;

       ///  15 、抽混合烟的人的邻居喝矿泉水 
        
       if(Math.Abs(find(3,3)-find(4,2))!=1)continue;
       ///  12 、抽BLUE MASTER烟的人喝啤酒
       ///  

       if(find(3,5)!=find(4,5))continue;

       for (i5=1;i5<=120;i5++)   ///宠物
       {     
        
        for(int j=0;j<5;j++,answer[j,5]=ALL[j,i5]);
        /// 10 、抽混合烟的人住在养鱼人的旁边
        /// 
        if(Math.Abs(find(3,3)-find(5,1))!=1)continue;

        ///  2 、瑞典人养了一条狗
        ///  
        if(find(2,5)!=find(5,5))continue;
        ///  6 、抽PALL MALL烟的人养了一只鸟 
        ///  
        if(find(3,4)!=find(5,4))continue;
        /// 11 、养马人住在DUNHILL烟的人旁边
        /// 

        if(Math.Abs(find(5,3)-find(3,1))!=1)continue;
        ///
        ///能活到这里的data,当然是答案喽
        ///
        write_answer();
 
       }
 
      }
     }
 
    }
   }
  }
         

  /// <summary>
  /// 非常典型的用递归实现排列组合算法。
  /// </summary>
  public void p()   
  {
   int nCount,nJudge,key;
   nLevel++;
   if(nLevel>5)
   {
    writeall();///有一种排列就写到All数组里
    nLevel--;
    return;
   }

   for(nCount=1;nCount<=5;nCount++)
   {
    key=0;
    for(nJudge=0;nJudge<=nLevel-1;nJudge++)
     if(nCount==List[nJudge])
     {
      key=1;
      break;
     }
  
    if(key==0)
    {
     List[nLevel]=nCount;
     p();
    }
   }
   nLevel--;
  }

  /// <summary>
  /// 写入all数组
  /// </summary>

  void writeall()
  {
   int i;
   for (i=1;i<=5;i++)
   {
    ALL[i,count]=List[i];
   }  
   count++;
  }

  int  find(int i,int j)
  {

   int k;
   for(k=0;k<=5;k++)
   {
    if (answer[k,i]==j)
    {
     return k;
    }
   }
   return -1;
  }

  /// <summary>
  /// 将答案打印出来
  /// </summary>
  void write_answer()
  {
   
   for (int i = 1;i<=5;i++)
   {
    for(int j=1 ;j<=5;j++)
    {
     Console.Write(data[i-1,answer[j,i]-1]+",");

    }
    Console.WriteLine();
   }
   Console.WriteLine();
  }
 }
}
说明:程序使用C#,在Microsoft Visual  Studio.net下编译执行通过。如果你没有Microsoft Visual C# 需要安装Microsoft(r) .NET Framework SDK ,把上述代码保存到ayst.cs,然后在命令行模式下执行csc ayst.cs ,然后执行ayst.exe也可以。这个程序是很久之前写的。当时只是为了得到答案,所以程序写的比较乱。让同行见笑了。以下是程序的运行结果(答案一总7种,没想到吧):
黄房子,蓝房子,红房子,绿房子,白房子,
挪威人,丹麦人,英国人,德国人,瑞典人,
DUNHILL,混合烟,PALL MALL,PRINCE,BLUE    MASTER,
矿泉水,茶,牛奶,咖 啡, 啤酒 ,
鱼,马,鸟, 恐龙,狗,

绿房子,蓝房子,黄房子,红房子,白房子,
挪威人,德国人,瑞典人,英国人,丹麦人,
混合烟,PRINCE,DUNHILL,BLUE      MASTER,PALL MALL,
咖 啡,矿泉水,牛奶, 啤酒 ,茶,
 恐龙,鱼,狗,马,鸟,

绿房子,蓝房子,白房子,黄房子,红房子,
挪威人,德国人,瑞典人,丹麦人,英国人,
PALL MALL,PRINCE,混合烟,DUNHILL,BLUE    MASTER,
咖 啡,矿泉水,牛奶,茶, 啤酒 ,
鸟,鱼,狗, 恐龙,马,

绿房子,蓝房子,白房子,黄房子,红房子,
挪威人,德国人,瑞典人,丹麦人,英国人,
PALL MALL,PRINCE,混合烟,DUNHILL,BLUE    MASTER,
咖 啡,矿泉水,牛奶,茶, 啤酒 ,
鸟, 恐龙,狗,鱼,马,

绿房子,蓝房子,白房子,红房子,黄房子,
挪威人,德国人,瑞典人,英国人,丹麦人,
PALL MALL,PRINCE,混合烟,BLUE    MASTER,DUNHILL,
咖 啡,矿泉水,牛奶, 啤酒 ,茶,
鸟,鱼,狗,马, 恐龙,

绿房子,蓝房子,红房子,黄房子,白房子,
挪威人,德国人,英国人,丹麦人,瑞典人,
PALL MALL,PRINCE,混合烟,DUNHILL,BLUE    MASTER,
咖 啡,矿泉水,牛奶,茶, 啤酒 ,
鸟,鱼,马, 恐龙,狗,

绿房子,蓝房子,红房子,黄房子,白房子,
挪威人,德国人,英国人,丹麦人,瑞典人,
PALL MALL,PRINCE,混合烟,DUNHILL,BLUE    MASTER,
咖 啡,矿泉水,牛奶,茶, 啤酒 ,
鸟, 恐龙,马,鱼,狗,

本文地址:http://com.8s8s.com/it/it45044.htm