找回密码
 入驻
搜索
查看: 44603|回复: 13

据说是爱因斯坦出的难题,我才用了十多分钟,郁闷:L

[复制链接]
发表于 2006-6-30 16:28:16 | 显示全部楼层 |阅读模式
据说是爱因斯坦在20世纪初出得这个难题,还说世界上有98%的答不出,我觉得有点难度,但不至于。
    在一条街上,有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香烟的人有一个喝水的邻居
问题: 谁养鱼

学程序的可能有优势,我用类的继承与派生的方法。
我的草图,发现它还有点艺术感;P

[ 本帖最后由 zkkpkk 于 2006-6-30 16:29 编辑 ]

草图

草图
发表于 2006-6-30 17:05:08 | 显示全部楼层
怎么爱因斯坦自己说的答案是挪威呢?~~~~~~~~~~~~~~
回复

使用道具 举报

 楼主| 发表于 2006-6-30 19:55:27 | 显示全部楼层
原帖由 骅灯初上 于 2006-6-30 17:05 发表
怎么爱因斯坦自己说的答案是挪威呢?~~~~~~~~~~~~~~

查过了,六种组合.........

  

//爱因斯坦难题  
//程序设计:万道濮  
//说明:此版本是完美版  
#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";  


  
作者: 手冢的笑  2006-1-10 15:29   回复此发言   

--------------------------------------------------------------------------------

2 [资料]爱因斯坦的难题的C++解法  
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' &brvbar;&brvbar; cmd=='Q')   
return 0; //退出程序  
else if(cmd=='k' &brvbar;&brvbar; 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 &brvbar;&brvbar; a==4 &brvbar;&brvbar; 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 &brvbar;&brvbar; 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 &brvbar;&brvbar; 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 &brvbar;&brvbar; 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 &brvbar;&brvbar; 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;}
回复

使用道具 举报

 楼主| 发表于 2006-6-30 19:56:17 | 显示全部楼层
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' &brvbar;&brvbar; cmd=='Q')   
return 0; //正常退出程序  
else if(cmd=='r' &brvbar;&brvbar; cmd=='R')   
goto key; //重新解答难题  
else goto s2;  
}//主程序main()结束  

最后答案:  
    正确答案一共有六个。
回复

使用道具 举报

发表于 2006-6-30 19:57:26 | 显示全部楼层
LZ真强~~~~不头疼的吗?
回复

使用道具 举报

 楼主| 发表于 2006-6-30 19:58:53 | 显示全部楼层
我只想出了一种组合,而且还是画出来后才回头用程序做的,这个程序员牛```````````````
回复

使用道具 举报

 楼主| 发表于 2006-6-30 20:00:41 | 显示全部楼层
原帖由 林林 于 2006-6-30 19:57 发表
LZ真强~~~~不头疼的吗?

我没那么强,这个程序是个网名叫什么家的程序员写的,我的那个嘛......嘿嘿菜:$
回复

使用道具 举报

发表于 2006-6-30 20:03:51 | 显示全部楼层
还以为你那么厉害呢~~~~~:L
回复

使用道具 举报

 楼主| 发表于 2006-6-30 20:06:36 | 显示全部楼层
原帖由 林林 于 2006-6-30 20:03 发表
还以为你那么厉害呢~~~~~:L

你以为啊,爆强的程序员写的
我的也有200多行,只得出一个,德国人的
回复

使用道具 举报

发表于 2006-6-30 20:30:23 | 显示全部楼层
c++啊C++.....................郁闷
回复

使用道具 举报

 楼主| 发表于 2006-6-30 20:43:08 | 显示全部楼层
原帖由 月狂*焱 于 2006-6-30 20:30 发表
c++啊C++.....................郁闷

C++啊C++我爱死你啦,我你给了我面向对象的基础;P
回复

使用道具 举报

发表于 2006-6-30 20:46:05 | 显示全部楼层
那个程序员是中国人吧
我们富强的日子不远了!!
回复

使用道具 举报

 楼主| 发表于 2006-6-30 20:52:23 | 显示全部楼层
原帖由 vivianeta 于 2006-6-30 20:46 发表
那个程序员是中国人吧
我们富强的日子不远了!!

很多人不用程序都做得出来,你可以像我那样画图,现在是不是爱因斯坦的我都怀疑
回复

使用道具 举报

发表于 2006-7-2 22:48:28 | 显示全部楼层
顶顶顶顶顶顶顶顶顶顶
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 入驻

本版积分规则

QQ|Archiver|手机版|小黑屋|思明论坛

GMT+8, 2024-10-10 18:20 , Processed in 0.013648 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表