C#轻松解决世纪迷题

转载 2005年04月28日 03:48:00

下面的问题相信很多人都听过:
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了。

不好意思啊。今天上课了,刚下课,现在公布答案:

 
下面的问题相信很多人都听过:
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,
咖 啡,矿泉水,牛奶,茶, 啤酒 ,
鸟, 恐龙,马,鱼,狗,

蓝桥杯 骰子迷题

题目: 标题:骰子迷题     小明参加了少年宫的一项趣味活动:每个小朋友发给一个空白的骰子(它的6个面是空白的,没有数字),要小朋友自己设计每个面写哪个数字。但有如下要求:     1. 每个面只能...
  • CRZ_CC
  • CRZ_CC
  • 2016年04月25日 11:22
  • 816

考研各校迷题!电子的

  • 2012年11月12日 13:51
  • 642KB
  • 下载

《Java迷题解惑》PDF

  • 2009年04月26日 03:55
  • 1.08MB
  • 下载

蓝桥杯 2013 2 骰子迷题

小明参加了少年宫的一项趣味活动:每个小朋友发给一个空白的骰子(它的6个面是空白的,没有数字),要小朋友自己设计每个面写哪个数字。但有如下要求: 1. 每个面只能填写 0 至 8 中的某一...
  • YYecust
  • YYecust
  • 2017年02月12日 20:34
  • 316

Java的终极迷题及答案

  • 2008年10月24日 18:42
  • 26KB
  • 下载

骰子迷题JAVA

骰子迷题题目:标题:骰子迷题 小明参加了少年宫的一项趣味活动:每个小朋友发给一个空白的骰子(它的6个面是空白的,没有数字),要小朋友自己设计每个面写哪个数字。但有如下要求: 1. 每个面只能填写 ...

Java迷题:等于,还是不等于? 装箱 拆箱 及IntegerCache 缓存机制

等于还是不等于? 看来看下面的一段代码:      代码片段1 Java代码   public static void main(final String[]...

Java迷题:等于,还是不等于?

等于还是不等于? 看来看下面的一段代码: 代码片段1 public static void main(final String[] args) {         Integer a = ne...

UVa 11549 计算器迷题(判重和Folyd判圈算法)

题意: 计算器谜题。有一个老式计算器,只能显示n位数字。有一天,你无聊了,于是输入一个整数k,然后反复平方,直到溢出。每次溢出时,计算器会显示出结果的最高n位和一个错误标记。然后清除错误标记,继续平...
  • PK0071
  • PK0071
  • 2013年11月13日 17:16
  • 795

NOIP2016T1 玩具迷题

数组+取余
  • ivy_uu
  • ivy_uu
  • 2016年12月01日 18:22
  • 269
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C#轻松解决世纪迷题
举报原因:
原因补充:

(最多只允许输入30个字)