爱因斯坦谜题解答三种算法比较.docx

上传人:b****3 文档编号:24729039 上传时间:2023-06-01 格式:DOCX 页数:51 大小:96.47KB
下载 相关 举报
爱因斯坦谜题解答三种算法比较.docx_第1页
第1页 / 共51页
爱因斯坦谜题解答三种算法比较.docx_第2页
第2页 / 共51页
爱因斯坦谜题解答三种算法比较.docx_第3页
第3页 / 共51页
爱因斯坦谜题解答三种算法比较.docx_第4页
第4页 / 共51页
爱因斯坦谜题解答三种算法比较.docx_第5页
第5页 / 共51页
点击查看更多>>
下载资源
资源描述

爱因斯坦谜题解答三种算法比较.docx

《爱因斯坦谜题解答三种算法比较.docx》由会员分享,可在线阅读,更多相关《爱因斯坦谜题解答三种算法比较.docx(51页珍藏版)》请在冰豆网上搜索。

爱因斯坦谜题解答三种算法比较.docx

爱因斯坦谜题解答三种算法比较

爱因斯坦谜题:

   在一条街上有颜色互不相同的五栋房子,不同国籍的人分别住在这五栋房子力,每人抽不同品牌的香烟,喝不同的饮料,养不同的宠物。

已知如下情况:

1. 英国人住红色房子里。

2. 瑞典人养狗。

3. 丹麦人喝茶。

4. 绿色房子坐落在白色房子的左面。

5. 绿色房子的主人喝咖啡。

6. 抽PallMall香烟的人养鸟。

7. 黄色房子的主人抽Dunhill香烟。

8. 挪威人住第一间房子。

9. 五座房子中间的那座的主人喝牛奶。

10.抽Blends香烟的住在养猫人的隔壁。

11.养马的人住在抽Dunhill香烟者的隔壁。

12.抽BlueMaster香烟的喝啤酒。

13.德国人抽Prince香烟。

14.挪威人住的房子在蓝色房子的隔壁。

15.抽Blends香烟的人有一个喝水的邻居。

问:

谁养鱼?

 

谜题的英文原文:

Letusassumethattherearefivehousesofdifferentcolorsnexttoeachotheronthesameroad.

Ineachhouselivesamanofadifferentnationality.Everymanhashisfavoritedrink,his

favoritebrandofcigarettes,andkeepspetsofaparticularkind.

1.TheEnglishmanlivesintheredhouse.

2.TheSwedekeepsdogs.

3.TheDanedrinkstea.

4.Thegreenhouseisjusttotheleftofthewhiteone.

5.Theownerofthegreenhousedrinkscoffee.

6.ThePallMallsmokerkeepsbirds.

7.TheowneroftheyellowhousesmokesDunhills.

8.Themaninthecenterhousedrinksmilk.

9.TheNorwegianlivesinthefirsthouse.

10.TheBlendsmokerhasaneighborwhokeepscats.

11.ThemanwhosmokesBlueMastersdrinksbier.

12.ThemanwhokeepshorseslivesnexttotheDunhillsmoker.

13.TheGermansmokesPrince.

14.TheNorwegianlivesnexttothebluehouse.

15.TheBlendsmokerhasaneighborwhodrinkswater.

Thequestiontobeansweredis:

Whokeepsfish?

 这道迷题出自1981年柏林的德国逻辑思考学院。

据说世界上只有2%的人能出答案。

就连大名鼎鼎的爱因斯坦也成为此题大伤脑筋,所以这道题也经常被国内外知名公司用做面试题目,相信许多朋友都只做出过一个答案,今天就用计算机来看看答案:

 C#代码(代码来源:

using System;

namespace netsafe.math

{

    public class ayst

    {

        /// 

        /// 问题中的所有元素

        /// 

        string[,] data = { {"黄房子","蓝房子","白房子","红房子","绿房子"},

                           {"挪威人","英国人","德国人","丹麦人","瑞典人"},

                           {"DUNHILL","PRINCE","混合烟", "PALL MALL","BLUE MASTER"},

                           {"咖 啡","矿泉水","茶","牛奶"," 啤酒 "},

                           {"鱼"," 恐龙","马",    "鸟","狗"}

                         };

        /// 

/// answer用来存放答案

        /// 

        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();

                            }

                        }

                    }

                }

            }

        }

        /// 

        /// 非常典型的用递归实现排列组合算法。

        /// 

        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--;

        }

        /// 

        /// 写入all数组

        /// 

        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;

        }

        /// 

        /// 将答案打印出来

        /// 

        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#代码如下(代码来源:

using System;

using System.Collections.Generic;

using System.Text;

namespace 爱因斯坦迷题1

{

    enum 国籍 { 英国, 瑞典, 丹麦, 挪威, 德国 };

    enum 颜色 { 红, 绿, 蓝, 黄, 白 };

    enum 宠物 { 鸟, 猫, 马, 鱼, 狗 };

    enum 饮料 { 水, 牛奶, 咖啡, 茶, 啤酒 };

    enum 香烟 { blends, blue, prince, dunhill, pall };

    public class ProTable

    {

        private const string rule = @"

            1、在一条街上,有5座房子,喷了5种颜色。

            2、每个房里住着不同国籍的人

            3、每个人喝不同的饮料,抽不同品牌的香烟,养不同的宠物

            问题是:

谁养鱼?

            提示:

            1、英国人住红色房子

            2、瑞典人养狗

            3、丹麦人喝茶

            4、绿色房子在白色房子左面

            5、绿色房子主人喝咖啡

            6、抽Pall Mall 香烟的人养鸟

            7、黄色房子主人抽Dunhill 香烟

            8、住在中间房子的人喝牛奶

            9、 挪威人住第一间房

            10、抽Blends香烟的人住在养猫的人隔壁

            11、养马的人住抽Dunhill 香烟的人隔壁

            12、抽Blue Master的人喝啤酒

            13、德国人抽Prince香烟

            14、挪威人住蓝色房子隔壁

            15、抽Blends香烟的人有一个喝水的邻居 ";

        public string Rule { get { return rule; } }

        private enum T { 国籍 = 0, 颜色, 宠物, 饮料, 香烟 };

        private const int N = 5;

        //求排列

        private static int[,] aid = new int[120, N];

        static ProTable()

        {

            int k = 0;

            for (int i0 = 0; i0 < N; i0++)

            {

                for (int i1 = 0; i1 < N; i1++)

                {

                    if (i1 == i0) continue;

                    for (int i2 = 0; i2 < N; i2++)

                    {

                        if (i2 == i1 || i2 == i0) continue;

                        for (int i3 = 0; i3 < N; i3++)

                        {

                            if (i3 == i2 || i3 == i1 || i3 == i0) continue;

                            for (int i4 = 0; i4 < N; i4++)

                            {

                                if (i4 == i3 || i4 == i2 || i4 == i1 || i4 == i0) continue;

                                aid[k, 0] = i0;

                                aid[k, 1] = i1;

                                aid[k, 2] = i2;

                      

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 小学作文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1