Board logo

Subject: 爱因斯坦的难题 [Print This Page]

Author: nuclear    Time: 2008-12-25 17:04     Subject: 爱因斯坦的难题

爱因斯坦在20世纪初出的这个谜语。他说世界上有98%的人答不出来。(不知道是真的假的
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香烟的人有一个喝水的邻居

多年以前曾在电脑报上看到过这个题目,下午上网无聊时在橙子的BLOG上又发现了这个题目
http://hi.baidu.com/rarnu/blog/item/e53883d6463be92807088b9b.html
就开玩笑的让他用delphi写个程序推理下,没想到一会就有了结果
program PrjEinstein;

{$APPTYPE CONSOLE}

uses
  SysUtils;

const
  fData: array[0..4] of string = ('国家','房子','宠物','饮料','香烟');

var
  fCountry: array[1..5] of string = ('','','','','');
  fHouseColor: array[1..5] of string = ('','','','','');
  fPet: array[1..5] of string = ('','','','','');
  fDrink: array[1..5] of string = ('','','','','');
  fSmoke: array[1..5] of string = ('','','','','');

var
  i, j, k, l, m, n, o, p, q, r, s, t: Integer;
  A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12: boolean;
begin
  for i := 1 to 5 do
  begin
    for j := 1 to 5 do
    begin
      for k := 1 to 5 do
      begin
        for l := 1 to 5 do
        begin
          for m := 1 to 5 do
          begin
            for n := 1 to 5 do
            begin
              for o := 1 to 5 do
              begin
                A1 := (i<>1) and (i<>2);  // (1)
                A2 := (j<>1) and (j<>i);  // (2)
                A3 := (k>3) and (k<>i);   // (4,5)
                A4 := (l<>1) and (l<>3) and (l<>i) and (l<>j) and (l<>k);  // (3)
                A5 := (m<>j);             // (6)
                A6 := (n<>2) and (n<>i) and (n<>k) and (n<>m);  // (7)
                A7 := (o<>3) and (o<>k) and (o<>l) and (o<>m) and (o<>n); // (12)
                if A1 and A2 and A3 and A4 and A5 and A6 and A7 then
                begin
                  p := 15-1-i-j-l;  // (13)
                  q := 15-m-n-o-p;   // (10)
                  A8 := (p<>1) and (p<>i) and (p<>j) and (p<>l) and (p<>m) and (p<>n) and (p<>o);  // (13)
                  A9 := (q<>m) and (q<>n) and (q<>o) and (q<>p);  // (10)
                  if A8 and A9 then
                  begin
                    if (q>1) and ((q-1)<>j) and ((q-1)<>m) then
                    begin
                      fPet[q-1] := '猫';
                      if (n>1) and ((n-1)<>j) and ((n-1)<>m) then
                      begin
                        fPet[n-1] := '马';
                        t := 15-(q-1)-(n-1)-j-m;
                        fPet[t] := '鱼';
                      end
                      else
                      begin
                        fPet[n+1] := '马';
                        t := 15-(q-1)-(n+1)-j-m;
                        fPet[t] := '鱼';
                      end;
                    end
                    else
                    begin
                      fPet[q+1] := '猫';
                      if (n>1) and ((n-1)<>j) and ((n-1)<>m) then
                      begin
                        fPet[n-1] := '马';
                        t := 15-(q+1)-(n-1)-j-m;
                        fPet[t] := '鱼';
                      end
                      else
                      begin
                        fPet[n+1] := '马';
                        t := 15-(q+1)-(n+1)-j-m;
                        fPet[t] := '鱼';
                      end;
                    end;
                    if (q>1) and ((q-1)<>3) and ((q-1)<>k) and ((q-1)<>l) and ((q-1)<>o) then  // (15)
                      fDrink[q-1] := '矿泉水'
                    else if (q<5) and ((q+1)<>3) and ((q+1)<>k) and ((q+1)<>l) and ((q+1)<>o) then    // (11)
                      fDrink[q+1] := '矿泉水';
                    if (((q>1) and ((q-1)<>j) and ((q-1)<>m)) or ((q<5)  and ((q+1)<>j) and ((q+1)<>m))) then   // (10)
                    begin
                      if(((q>1) and ((q-1)<>3) and ((q-1)<>k) and ((q-1)<>l) and ((q-1)<>o)) or ((q<5) and ((q+1)<>3) and ((q+1)<>k) and ((q+1)<>l) and ((q+1)<>o))) then // (15)
                      begin
                        if(((n>1) and ((n-1)<>j) and ((n-1)<>m)) or ((n<5) and ((n+1)<>j) and ((n+1)<>m))) then // (11)
                        begin
                          fCountry := '英国'; // (1)
                          fHouseColor := '红色';
                          fCountry[j] := '瑞典';  // (2)
                          fPet[j] := '狗';
                          fHouseColor[k] := '绿色'; // (4)
                          fHouseColor[k-1] := '白色';
                          fDrink[k] := '咖啡';   // (5)
                          fCountry[l] := '丹麦';    // (3)
                          fDrink[l] := '茶';
                          fSmoke[m] := 'PallMall';  // (6)
                          fPet[m] := '鸟';
                          fHouseColor[n] := '黄色';  // (7)
                          fSmoke[n] := 'Dunhill';
                          fSmoke[o] := 'BlueMaster';  // (12)
                          fDrink[o] := '啤酒';
                          fCountry[p] := '德国';  // (13)
                          fSmoke[p] := 'Prince';
                          fSmoke[q] := 'Blends';  // (10)
                          fCountry[1] := '挪威';   // (9)
                          fHouseColor[2] := '蓝色';  // (14)
                          fDrink[3] := '牛奶';     // (8)
                          for r := 0 to 4 do
                          begin
                            Write(Format('%12s',[fData[r]]));
                          end;
                          WriteLn(#13#10);
                          for s := 1 to 5 do
                          begin
                            Write(Format('%12s',[fCountry[s]]));
                            Write(Format('%12s',[fHouseColor[s]]));
                            Write(Format('%12s',[fPet[s]]));
                            Write(Format('%12s',[fDrink[s]]));
                            Write(Format('%16s',[fSmoke[s]]));
                            Write(#13#10);
                          end;
                          ReadLn;
                          Exit;
                        end;
                      end;
                    end;
                  end;
                end;
              end;
            end;
          end;
        end;
      end;
    end;
  end;
end.
Author: rarnu    Time: 2008-12-25 17:58

orz。。。我终于成功的上来了。。。
Author: rarnu    Time: 2008-12-25 17:59

代码混乱了。。。后面都是斜体。。。
以后直接加Code标签

(*
(1)英国人住红色房子
(2)瑞典人养狗
(3)丹麦人喝茶
(4)绿色房子在白色房子左面
(5)绿色房子主人喝咖啡
(6)抽Pall Mall香烟的人养鸟
(7)黄色房子主人抽Dunhill香烟
(8)住在中间房子的人喝牛奶
(9)挪威人住第一间房
(10)抽Blends香烟的人住在养猫的人隔壁
(11)养马的人住抽Dunhill香烟的人隔壁
(12)抽Blue Master的人喝啤酒
(13)德国人抽Prince香烟
(14)挪威人住蓝色房子隔壁
(15)抽Blends香烟的人有一个喝矿泉水的邻居
*)

program PrjEinstein;

{$APPTYPE CONSOLE}

uses
  SysUtils;

const
  fData: array[0..4] of string = ('国家','房子','宠物','饮料','香烟');

var
  fCountry: array[1..5] of string = ('','','','','');
  fHouseColor: array[1..5] of string = ('','','','','');
  fPet: array[1..5] of string = ('','','','','');
  fDrink: array[1..5] of string = ('','','','','');
  fSmoke: array[1..5] of string = ('','','','','');

var
  i, j, k, l, m, n, o, p, q, r, s, t: Integer;
  A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12: boolean;
begin
  for i := 1 to 5 do
  begin
    for j := 1 to 5 do
    begin
      for k := 1 to 5 do
      begin
        for l := 1 to 5 do
        begin
          for m := 1 to 5 do
          begin
            for n := 1 to 5 do
            begin
              for o := 1 to 5 do
              begin
                A1 := (i<>1) and (i<>2);  // (1)
                A2 := (j<>1) and (j<>i);  // (2)
                A3 := (k>3) and (k<>i);   // (4,5)
                A4 := (l<>1) and (l<>3) and (l<>i) and (l<>j) and (l<>k);  // (3)
                A5 := (m<>j);             // (6)
                A6 := (n<>2) and (n<>i) and (n<>k) and (n<>m);  // (7)
                A7 := (o<>3) and (o<>k) and (o<>l) and (o<>m) and (o<>n); // (12)
                if A1 and A2 and A3 and A4 and A5 and A6 and A7 then
                begin
                  p := 15-1-i-j-l;  // (13)
                  q := 15-m-n-o-p;   // (10)
                  A8 := (p<>1) and (p<>i) and (p<>j) and (p<>l) and (p<>m) and (p<>n) and (p<>o);  // (13)
                  A9 := (q<>m) and (q<>n) and (q<>o) and (q<>p);  // (10)
                  if A8 and A9 then
                  begin
                    if (q>1) and ((q-1)<>j) and ((q-1)<>m) then
                    begin
                      fPet[q-1] := '猫';
                      if (n>1) and ((n-1)<>j) and ((n-1)<>m) then
                      begin
                        fPet[n-1] := '马';
                        t := 15-(q-1)-(n-1)-j-m;
                        fPet[t] := '鱼';
                      end
                      else
                      begin
                        fPet[n+1] := '马';
                        t := 15-(q-1)-(n+1)-j-m;
                        fPet[t] := '鱼';
                      end;
                    end
                    else
                    begin
                      fPet[q+1] := '猫';
                      if (n>1) and ((n-1)<>j) and ((n-1)<>m) then
                      begin
                        fPet[n-1] := '马';
                        t := 15-(q+1)-(n-1)-j-m;
                        fPet[t] := '鱼';
                      end
                      else
                      begin
                        fPet[n+1] := '马';
                        t := 15-(q+1)-(n+1)-j-m;
                        fPet[t] := '鱼';
                      end;
                    end;
                    if (q>1) and ((q-1)<>3) and ((q-1)<>k) and ((q-1)<>l) and ((q-1)<>o) then  // (15)
                      fDrink[q-1] := '矿泉水'
                    else if (q<5) and ((q+1)<>3) and ((q+1)<>k) and ((q+1)<>l) and ((q+1)<>o) then    // (11)
                      fDrink[q+1] := '矿泉水';
                    if (((q>1) and ((q-1)<>j) and ((q-1)<>m)) or ((q<5)  and ((q+1)<>j) and ((q+1)<>m))) then   // (10)
                    begin
                      if(((q>1) and ((q-1)<>3) and ((q-1)<>k) and ((q-1)<>l) and ((q-1)<>o)) or ((q<5) and ((q+1)<>3) and ((q+1)<>k) and ((q+1)<>l) and ((q+1)<>o))) then // (15)
                      begin
                        if(((n>1) and ((n-1)<>j) and ((n-1)<>m)) or ((n<5) and ((n+1)<>j) and ((n+1)<>m))) then // (11)
                        begin
                          fCountry[i] := '英国'; // (1)
                          fHouseColor[i] := '红色';
                          fCountry[j] := '瑞典';  // (2)
                          fPet[j] := '狗';
                          fHouseColor[k] := '绿色'; // (4)
                          fHouseColor[k-1] := '白色';
                          fDrink[k] := '咖啡';   // (5)
                          fCountry[l] := '丹麦';    // (3)
                          fDrink[l] := '茶';
                          fSmoke[m] := 'PallMall';  // (6)
                          fPet[m] := '鸟';
                          fHouseColor[n] := '黄色';  // (7)
                          fSmoke[n] := 'Dunhill';
                          fSmoke[o] := 'BlueMaster';  // (12)
                          fDrink[o] := '啤酒';
                          fCountry[p] := '德国';  // (13)
                          fSmoke[p] := 'Prince';
                          fSmoke[q] := 'Blends';  // (10)
                          fCountry[1] := '挪威';   // (9)
                          fHouseColor[2] := '蓝色';  // (14)
                          fDrink[3] := '牛奶';     // (8)
                          for r := 0 to 4 do
                          begin
                            Write(Format('%12s',[fData[r]]));
                          end;
                          WriteLn(#13#10);
                          for s := 1 to 5 do
                          begin
                            Write(Format('%12s',[fCountry[s]]));
                            Write(Format('%12s',[fHouseColor[s]]));
                            Write(Format('%12s',[fPet[s]]));
                            Write(Format('%12s',[fDrink[s]]));
                            Write(Format('%12s',[fSmoke[s]]));
                            Write(#13#10);
                          end;
                          ReadLn;
                          Exit;
                        end;
                      end;
                    end;
                  end;
                end;
              end;
            end;
          end;
        end;
      end;
    end;
  end;
end.


Author: Passion    Time: 2008-12-25 18:13

光看见这堆end了:
                        end;
                      end;
                    end;
                  end;
                end;
              end;
            end;
          end;
        end;
      end;
    end;
  end;
end.
Author: dapro    Time: 2009-1-2 18:57

穷举。。。 逐个排除!有空我用C++推导下
Author: dapro    Time: 2009-1-2 19:14

推导了3分钟
得出了一点结论!
累了吃饭!明天晚上继续


从左到右数
房子1=挪威人
房子2=蓝色
房间3=喝牛奶
房间4=绿色
房间5=白色

住红色房子的主人是英国人
住绿色房子的主人喝咖啡
住白色房子的主人喝牛奶
住黄色房子的主人抽Dunhill香烟
住蓝色房子的
Author: dapro    Time: 2009-1-2 19:15

奇怪了,
我电脑显示未19:01
到BBS上变成19:14
唉...我就想那么长的时间怎么可能才3分钟
Author: bahamut8348    Time: 2009-1-18 20:21

屁股后面的那堆end的确够牛B..............




Welcome to CnPack Forum (http://bbs.cnpack.org/) Powered by Discuz! 5.0.0