肝胆相照论坛

 

 

肝胆相照论坛 论坛 两广版 存档 1 [讨论]爱因斯坦的问题
查看: 432|回复: 7

[讨论]爱因斯坦的问题 [复制链接]

Rank: 6Rank: 6

现金
2816 元 
精华
帖子
1228 
注册时间
2004-12-15 
最后登录
2013-2-7 
1
发表于 2006-3-9 07:13

同事给我出了一道题目,问我能不能做出来?还要记下解答过程的时间。乖乖,花了我半个小时

呀。觉得好玩,也传上来给大家玩玩。


  问题是:在一条街上,有5座房子,喷了5种颜色;每个房里住着不同国籍的人;每个人喝不同的饮

料,抽不同品牌的香烟养不同的宠物。

请问:谁养鱼?
  

提示:

1. 英国人住红色房子

2. 瑞典人养狗

3. 丹麦人喝茶

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

  5. 绿色房子主人喝咖啡

  6. 抽pall mall 香烟的人养鸟

  7. 黄色房子主人抽dunhill 香烟

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

  9. 挪威人住第一间房

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

  11. 养马的人住抽dunhill 香烟的人隔壁

  12. 抽blue master的人喝啤酒

  13. 德国人抽prince香烟

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

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

据说是爱因斯坦提出的一个问题。他老人家的推理能力实在很厉害。

Rank: 6Rank: 6

现金
3341 元 
精华
帖子
1925 
注册时间
2004-8-6 
最后登录
2017-11-27 
2
发表于 2006-3-9 13:15

美女的帖子

先占了沙发慢慢看

[em07]
2008了

Rank: 6Rank: 6

现金
3341 元 
精华
帖子
1925 
注册时间
2004-8-6 
最后登录
2017-11-27 
3
发表于 2006-3-9 13:16

好像是很老的题了啊

2008了

Rank: 7Rank: 7Rank: 7

现金
4020 元 
精华
帖子
994 
注册时间
2004-7-10 
最后登录
2013-1-27 
4
发表于 2006-3-9 13:25
负尽千重难,炼的不死心!

Rank: 3Rank: 3

现金
296 元 
精华
帖子
35 
注册时间
2006-3-7 
最后登录
2006-6-6 
5
发表于 2006-3-9 13:26

字也太小了吧,我本来就近视,看得好辛苦啊!

Rank: 7Rank: 7Rank: 7

现金
4020 元 
精华
帖子
994 
注册时间
2004-7-10 
最后登录
2013-1-27 
6
发表于 2006-3-9 13:28
爱因斯坦难题C++解法


解法:
利用数组和循环:
用5个数组(数组名)表示5种属性,用1、2、3、4、5分别代替各种属性的具体取值
数组的下标表示房间号,数组元素的取值表示某房间某属性的具体取值的代号
房间号(即数组下标)也表示方位,房间号小的为左,大的为右,下标相邻即房间相邻

房间 0 1 2 3 4

国家 挪 德 瑞 英 丹 ---> a[5]
颜色 绿 蓝 黄 红 白 ---> b[5]
饮品 咖 水 奶 酒 茶 ---> c[5]
香烟 blends prince dunhill blue pall ---> d[5]
宠物 鱼 猫 狗 马 鸟 ---> e[5]

取值 1 2 3 4 5 ---> 数组元素的取值

条件化简:
1 英---红 若a=4,则b=4
2 瑞---狗 若a=3,则e=3
3 丹---茶 若a=5,则c=5
4 绿---在白左面 若b=1,b[j]=5,则i<j
5 绿---咖 若b=1,则c=1
6 鸟---pall 若e=5,则d=5
7 黄---dunhill 若b=3,则d=3
8 中间房子---奶 c[2]=3
9 挪---第1间房 a[0]=1
10 猫---有blends邻居 若e=2,则d[i-1]=1 ¦¦ d[i+1]=1
11 马---有dunhill邻居 若e=4,则d[i-1]=3 ¦¦ d[i+1]=3
12 酒---blue 若c=4,则d=4
13 德---prince 若a=2,则d=2
14 挪---有蓝邻居 ==〉b[1]=2
15 水---有blends邻居 若c=2,则d[i-1]=1 ¦¦ d[i+1]=1

C++源代码:
#include<iostream.h>

int main()
{
cout<<endl;
cout<<" * 爱因斯坦难题 * \n";
cout<<" 程序设计开发:万道濮\n";
cout<<" [2005.1.15]\n";
cout<<"================================================================================";
int a[5],b[5],c[5],d[5],e[5],t[120][5]; //定义所需数组
int i,j,c1,c2,c3,c4,p1,p2,p3,p4,p5; //定义所需变量
char cmd; //cmd用来暂存用户输入的命令
int k; //k用来计数

cout<<" 传说下面是爱因斯坦在20世纪初出的一道测试题。他说世界上有99%的人回答不出这道题,看看你是否属于另外的1%?题目如下:\n";
cout<<"\n前提:\n";
cout<<" 1 有五栋五种颜色的房子\n";
cout<<" 2 每一位房子的主人国籍都不同\n";
cout<<" 3 这五个人每人只喝一种饮料,只抽一种牌子的香烟,只养一种宠物 \n";
cout<<" 4 没有人有相同的宠物,抽相同牌子的香烟,喝相同的饮料 \n";
cout<<"条件:\n";
cout<<" 1 英国人住在红房子里 \n";

cout<<" 2 瑞典人养了一条狗 \n";
cout<<" 3 丹麦人喝茶\n";
cout<<" 4 绿房子在白房子左边 \n";
cout<<" 5 绿房子主人喝咖啡 \n";
cout<<" 6 抽PALL MALL烟的人养了一只鸟 \n";
cout<<" 7 黄房子主人抽DUNHILL烟\n";
cout<<" 8 住在中间那间房子的人喝牛奶 \n";
cout<<" 9 挪威人住第一间房子 \n";
cout<<" 10 抽BLENDS烟的人住在养猫人的旁边\n";
cout<<" 11 养马人住在DUNHILL烟的人旁边 \n";
cout<<" 12 抽BLUE MASTER烟的人喝啤酒\n";
cout<<" 13 德国人抽PRINCE烟 \n";
cout<<" 14 挪威人住在蓝房子旁边 \n";
cout<<" 15 抽BLENDS烟的人的邻居喝矿泉水\n";
cout<<"问题:谁养鱼?\n";
cout<<"\n";
sl: cout<<"输入“k”开始解答此难题,输入“q”退出程序:";
cin>>cmd;
cout<<endl;
if(cmd=='q' ¦¦ cmd=='Q')
return 0; //退出程序
else if(cmd=='k' ¦¦ cmd=='K')
goto key; //开始解答难题
else goto sl;

//先求1、2、3、4、5五个数字的所有排列情况
//下面开始用排列组合的方法排列5个数字
key:k=0; //k记录排列组合的种数
p1=0; //初始化下面循环所需参数为0
while(5-p1) //先放置数字1,数字1有5个位置可以选择
{
for(i=0;i<5;i++) //每次从下层循环回到此处都要先清空上次的排列
a=0;
p1++; //p1记录数字1的当前放置次数
for(i=0,c1=0;i<5;i++)
if(a==0) {c1++; if(c1==p1) {a=1; i=5;}} //放置数字1

p2=0; //初始化下面循环所需参数为0
while(4-p2) //放置数字2,放置好数字1后,数字2有4个位置可以选择
{
for(i=0;i<5;i++) //每次从下层循环回到此处都要先清除上次排列中的2、3、4、5
if(a!=1) a=0;
p2++; //p2记录数字2的当前放置次数
for(i=0,c2=0;i<5;i++)
if(a==0) {c2++; if(c2==p2) {a=2; i=5;}}

p3=0; //初始化下面循环所需参数为0
while(3-p3) //放置数字3,放置好数字2后,数字3有3个位置可以选择
{
for(i=0;i<5;i++) //每次从下层循环回到此处都要先清除上次排列中的3、4、5
if(a==3 ¦¦ a==4 ¦¦ a==5) a=0;
p3++; //p3记录数字3的当前放置次数
for(i=0,c3=0;i<5;i++)
if(a==0) {c3++; if(c3==p3) {a=3;i=5;}}

p4=0; //初始化下面循环所需参数为0
while(2-p4) //放置数字4,放置好数字3后,数字4有2个位置可以选择
{
for(i=0;i<5;i++) //每次从下层循环回到此处都要先清除上次排列中的4、5
if(a==4 ¦¦ a==5) a=0;
p4++; //p4记录数字4的当前放置次数
for(i=0,c4=0;i<5;i++)
if(a==0) {c4++; if(c4==p4) {a=4;i=5;}}

for(i=0;i<5;i++) //放置数字5,放置好数字4后,只剩1个位置来放5,故不用循环
if(a==0) {a=5;i=5;} //k记录排列组合的种数

//五个数字的一种排列完成,将此排列记录在数组t[k][5]中
for(i=0;i<5;i++)
{t[k]=a;}
k++; //k记录排列组合的种数
}
}
}
}
//1、2、3、4、5五个数字的所有排列情况算完,都记录在数组t[][]中
//下面开始用t[][]中的排列组合所有属性,并判断这种组合是否满足题意
k=0; //k记录正确答案的个数
p1=0;
while(120-p1) //通过循环组合“国家”属性
{ //9 挪---第1间房 ==>a[0]=1
if(t[p1][0]!=1) {p1++; continue;} //9 挪---第1间房 a[0]=1
for(i=0;i<5;i++) {a=t[p1];} //a[]放置上第p1种国家属性的排列
p1++; //p1指向下一种排列情况

p2=0;
while(120-p2) //通过循环组合“颜色”属性
{ //14 挪---有蓝邻居 ==>b[1]=2
if(t[p2][1]!=2) {p2++; continue;} //14 挪---有蓝邻居 ==〉b[1]=2
for(i=0;i<5;i++) {b=t[p2];} //
p2++; //p1指向下一种排列情况

p3=0;
while(120-p3) //通过循环组合“饮品”属性
{ //8 中间房子---奶 ==>c[2]=3
if(t[p3][2]!=3) {p3++; continue;} //8 中间房子---奶 c[2]=3
for(i=0;i<5;i++) {c=t[p3];} //
p3++; //p1指向下一种排列情况

p4=0;
while(120-p4) //通过循环组合“香烟”属性
{
for(i=0;i<5;i++) {d=t[p4];}
p4++;

p5=0;
while(120-p5) //通过循环组合“宠物”属性
{
for(i=0;i<5;i++) {e=t[p5];}
p5++;

/*测试
cout<<" 房间 国家 颜色 饮品 香烟 宠物\n\n";
for(i=0;i<5;i++)
{
cout<<" "<<i+1<<" "<<a<<" "<<b<<" "<<c<<" "<<d<<" "<<e<<endl;
}
//return 0;
//测试完毕*/

//所有属性的一种组和完成,下面判断这种组合是否满足题意
//若有一个条件不满足,就退出本次循环,并继续下次循环,即下一组组合

//1 英---红 若a=4,则b=4
for(i=0;i<5;i++)
{if(a==4) break;}
if(b!=4) continue; //退出本次循环,并继续下次循环,即下一组组合

//2 瑞---狗 若a=3,则e=3
for(i=0;i<5;i++)
{if(a==3) break;}
if(e!=3) continue; //退出本次循环,并继续下次循环,即下一组组合

//3 丹---茶 若a=5,则c=5
for(i=0;i<5;i++)
{if(a==5) break;}
if(c!=5) continue; //退出本次循环,并继续下次循环,即下一组组合

//4 绿---在白左面 若b=1,b[j]=5,则i<j
for(i=0;i<5;i++)
{if(b==1) break;}
for(j=0;j<5;j++)
{if(a[j]==5) break;}
if(i>=j) continue; //退出本次循环,并继续下次循环,即下一组组合

//5 绿---咖 若b=1,则c=1
for(i=0;i<5;i++)
{if(b==1) break;}
if(c!=1) continue;

//6 鸟---pall 若e=5,则d=5
for(i=0;i<5;i++)
{if(e==5) break;}
if(d!=5) continue;

//7 黄---dunhill 若b=3,则d=3
for(i=0;i<5;i++)
{if(b==3) break;}
if(d!=3) continue;

//10 猫---有blends邻居 若e=2,则d[i-1]=1 ¦¦ d[i+1]=1
for(i=0;i<5;i++)
{if(e==2) break;}
if(i==0) {if(d[i+1]!=1) continue;}
if(i>0 && i<4) {if(d[i-1]!=1 && d[i+1]!=1) continue;}
if(i==4) {if(d[i-1]!=1) continue;}

//11 马---有dunhill邻居 若e=4,则d[i-1]=3 ¦¦ d[i+1]=3
for(i=0;i<5;i++)
{if(e==4) break;}
if(i==0) {if(d[i+1]!=3) continue;}
if(i>0 && i<4) {if(d[i-1]!=3 && d[i+1]!=3) continue;}
if(i==4) {if(d[i-1]!=3) continue;}

//12 酒---blue 若c=4,则d=4
for(i=0;i<5;i++)
{if(c==4) break;}
if(d!=4) continue;

//13 德---prince 若a=2,则d=2
for(i=0;i<5;i++)
{if(a==2) break;}
if(d!=2) continue;

//15 水---有blends邻居 若c=2,则d[i-1]=1 ¦¦ d[i+1]=1
for(i=0;i<5;i++)
{if(c==2) break;}
if(i==0) {if(d[i+1]!=1) continue;}
if(i>0 && i<4) {if(d[i-1]!=1 && d[i+1]!=1) continue;}
if(i==4) {if(d[i-1]!=1) continue;}

//所有条件都判断完毕,若程序执行到此而没有退出本次循环
//说明此组合满足题意,是正确答案,下面就输出这种组合
//输出答案后,继续判断下一种组合,看是否还有其他答案
k++; //k记录正确答案的个数
cout<<"\n————————爱因斯坦难题答案————————\n\n";
//下面输出所问问题的答案
cout<<" 第"<<k<<"种答案: ";
for(i=0;i<5;i++) //寻找养鱼的人对应的数组元素
{if(e==1) break;}
switch (a)
{
case 1: cout<<"挪威人养鱼\n\n";
break;
case 2: cout<<"德国人养鱼\n\n";
break;
case 3: cout<<"瑞士人养鱼\n\n";
break;
case 4: cout<<"英国人养鱼\n\n";
break;
case 5: cout<<"丹麦人养鱼\n\n";
break;
}//问题答案输出完毕
cout<<" 左 <---|---> 右\n\n";
cout<<" 房间 1 2 3 4 5\n\n";
//输出答案的所有“国家”属性
cout<<" 国家 ";
for(i=0;i<5;i++)
{
switch (a)
{
case 1: cout<<"挪威 ";
break;
case 2: cout<<"德国 ";
break;
case 3: cout<<"瑞士 ";
break;
case 4: cout<<"英国 ";
break;
case 5: cout<<"丹麦 ";
break;
}
}
cout<<"\n\n"; //换行
//输出答案的所有“颜色”属性
cout<<" 颜色 ";
for(i=0;i<5;i++)
{
switch (b)
{
case 1: cout<<"绿色 ";
break;
case 2: cout<<"蓝色 ";
break;
case 3: cout<<"黄色 ";
break;
case 4: cout<<"红色 ";
break;
case 5: cout<<"白色 ";
break;
}
}
cout<<"\n\n"; //换行
//输出答案的所有“饮品”属性
cout<<" 饮品 ";
for(i=0;i<5;i++)
{
switch (c)
{
case 1: cout<<"咖啡 ";
break;
case 2: cout<<"泉水 ";
break;
case 3: cout<<"牛奶 ";
break;
case 4: cout<<"啤酒 ";
break;
case 5: cout<<"绿茶 ";
break;
}
}
cout<<"\n\n"; //换行
//输出答案的所有“香烟”属性
cout<<" 香烟 ";
for(i=0;i<5;i++)
{
switch (d)
{
case 1: cout<<"blends ";
break;
case 2: cout<<"prince ";
break;
case 3: cout<<"dunhill ";
break;
case 4: cout<<"blue ";
break;
case 5: cout<<"pall ";
break;
}
}
cout<<"\n\n"; //换行
//输出答案的所有“宠物”属性
cout<<" 宠物 ";
for(i=0;i<5;i++)
{
switch (e)
{
case 1: cout<<"鱼 ";
break;
case 2: cout<<"猫 ";
break;
case 3: cout<<"狗 ";
break;
case 4: cout<<"马 ";
break;
case 5: cout<<"鸟 ";
break;
}
}//答案的所有属性输出完毕
cout<<"\n\n"; //换行
}//通过循环组合“宠物”属性的循环完毕
}//通过循环组合“香烟”属性的循环完毕
}//通过循环组合“饮品”属性的循环完毕
}//通过循环组合“颜色”属性的循环完毕
}//通过循环组合“国家”属性的循环完毕
cout<<endl;
cout<<"====================计算完毕===================\n\n";
cout<<" 一共有以上 "<<k<<"种正确答案\n\n";
cout<<"================程序设计:万道濮===============\n\n";
s2: cout<<"输入“r”重新解答此难题,输入“q”退出程序:";
cin>>cmd;
cout<<endl;
if(cmd=='q' ¦¦ cmd=='Q')
return 0; //正常退出程序
else if(cmd=='r' ¦¦ cmd=='R')
goto key; //重新解答难题
else goto s2;
}//主程序main()结束

负尽千重难,炼的不死心!

Rank: 5Rank: 5

现金
3360 元 
精华
帖子
1002 
注册时间
2004-5-29 
最后登录
2010-9-11 
7
发表于 2006-3-9 13:40
有空回家多陪一下家人,老人不图你会解爱死的问题
分的分 走的走 去的早已去惯 赶一天 醉半晚 便能填补空间 得一些 失一些 淡得不会再淡 心想哭 却会笑 做人何必多贪

Rank: 4

现金
2376 元 
精华
帖子
219 
注册时间
2005-3-27 
最后登录
2014-9-23 
8
发表于 2006-3-10 02:42

以前好钟意做里类型即题架,自闭左四年罗,记忆力都差左,好多也都唔愿用脑去林,不愿开动脑筋,现在变呆啦,蠢左了.生锈了,自己也不喜欢自己讨厌自己.....

有边个有好介绍点提高记忆力架~~~~已家睇下边个行就唔记得上一行讲乜了.....有没人有建议啊~~~~仲有可以段练高思维空间还有想象能力的等等我都喜欢啊~~唔知点解啊.....只系已家蠢左啊~~~~唔该晒~~

‹ 上一主题|下一主题

肝胆相照论坛

GMT+8, 2024-10-6 00:27 , Processed in 0.016920 second(s), 11 queries , Gzip On.

Powered by Discuz! X1.5

© 2001-2010 Comsenz Inc.