标题:[原创]爱因斯坦给出的智力测验题
取消只看楼主
yu_hua
Rank: 2
等 级:论坛游民
帖 子:222
专家分:95
注 册:2006-8-10
结帖率:71.43%
 问题点数:0 回复次数:10 
[原创]爱因斯坦给出的智力测验题
*/ --------------------------------------------------------------------------------------
*/ 出自: 编程中国 http://www.bc-cn.net
*/ 作者: yu_hua
*/ 时间: 2007-11-10 编程论坛首发
*/ 声明: 尊重作者劳动,转载请保留本段文字
*/ --------------------------------------------------------------------------------------

题目是:
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香烟的人有一个喝水的邻居

问题是:谁养鱼?


搜索更多相关主题的帖子: 爱因斯坦 智力测验 
2007-11-10 21:12
yu_hua
Rank: 2
等 级:论坛游民
帖 子:222
专家分:95
注 册:2006-8-10
得分:0 

/*爱因斯坦难题的C语言程序设计(原创)*/
#include<stdio.h>
char*COL[]={NULL,"红","黄","绿","蓝","白"};
char*PAD[]={NULL,"狗","猫","鱼","鸟","马"};
char*DRK[]={NULL,"茶 ","牛奶","咖啡","啤酒","水 "};
char*GUO[]={NULL,"挪威","英国","德国","丹麦","瑞典"};
char*SMK[]={NULL,"Blends","BlueMaster","Dunhill","Pall Mall","Prince"};
struct{ char guojia, color, pads, drink, smoke; } aa[5];
int OK(void)
{
int i,j;
for(i=0;i<5;i++)
if(aa[i].guojia==2 && aa[i].color==1)goto next1;
return 0;
next1:
for(i=0;i<5;i++)
if(aa[i].guojia==5 && aa[i].pads==1)goto next2;
return 0;
next2:
for(i=0;i<5;i++)
if(aa[i].guojia==4 && aa[i].drink==1)goto next3;
return 0;
next3:
for(i=0;i<5;i++)
if(aa[i].color==3)goto next3_1;
return 0;
next3_1:
for(j=i+1;j<5;j++)
if(aa[j].color==5)goto next4;
return 0;
next4:
for(i=0;i<5;i++)
if(aa[i].color==3 && aa[i].drink==3)goto next5;
return 0;
next5:
for(i=0;i<5;i++)
if(aa[i].smoke==4 && aa[i].pads==4)goto next6;
return 0;
next6:
for(i=0;i<5;i++)
if(aa[i].color==2 && aa[i].smoke==3)goto next7;
return 0;
next7:
for(i=0;i<5;i++)
if(aa[i].guojia==3 && aa[i].smoke==5)goto next10;
return 0;
next10:
for(i=0;i<5;i++)
if(aa[i].smoke==2 && aa[i].drink==4)goto next11;
return 0;
next11:
for(i=0;i<5;i++)
if(aa[i].smoke==3)goto next12_1;
next12_1:
if(i==0){if(aa[1].pads==5)goto next13;}
else if(i==4){if(aa[3].pads==5)goto next13;}
else if(aa[i-1].pads==5||aa[i+1].pads==5)goto next13;
return 0;
next13:
for(i=0;i<5;i++)
if(aa[i].smoke==1)goto next13_1;
next13_1:
if(i==0){if(aa[1].pads==2)goto next14;}
else if(i==4){if(aa[3].pads==2)goto next14;}
else if(aa[i-1].pads==2||aa[i+1].pads==2)goto next14;
return 0;
next14:
for(i=0;i<5;i++)
if(aa[i].smoke==1)goto next14_1;
next14_1:
if(i==0){if(aa[1].drink==5)goto next15;}
else if(i==4){if(aa[3].drink==5)goto next15;}
else if(aa[i-1].drink==5||aa[i+1].drink==5)goto next15;
return 0;
next15:
return 1;
}

char color[4]={1,2,3,5};
char drink[4]={1,3,4,5};
char guojia[4]={2,3,4,5};
char smoke[]={1,2,3,4,5};
char pads[5]={1,2,3,4,5};

int rot(char a[],int n)
{ int i,j,k,t;
for(k=n-1;k>0;k--)
if(a[k-1]<a[k])break;
if(k==0)
{ for(i=0,j=n-1;i<j;i++,j--)
{char t=a[i];
a[i]=a[j];
a[j]=t;
}
return 0;
}
t=a[k-1];i=k;
for(j=k+1;j<n;j++)
if(t<a[j]&&a[j]<a[i])i=j;
a[k-1]=a[i];a[i]=t;
for(i=k;i<n-1;i++)
for(j=k;j<n-1+k-i;j++)
if(a[j]>a[j+1])
{ t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
return 1;
}

int main()
{ int i,j,k,ans=0;
int i1,i2,i3,i4,i5;
aa[1].color=4;
aa[2].drink=2;
aa[0].guojia=1;
for(i1=0;i1<24;i1++){
aa[0].color=color[0];
aa[2].color=color[1];
aa[3].color=color[2];
aa[4].color=color[3];
rot(color,4);
for(i2=0;i2<24;i2++){
aa[0].drink=drink[0];
aa[1].drink=drink[1];
aa[3].drink=drink[2];
aa[4].drink=drink[3];
rot(drink,4);
for(i3=0;i3<24;i3++){
aa[1].guojia=guojia[0];
aa[2].guojia=guojia[1];
aa[3].guojia=guojia[2];
aa[4].guojia=guojia[3];
rot(guojia,4);
for(i4=0;i4<120;i4++){
for(i=0;i<5;i++)
aa[i].smoke=smoke[i];
rot(smoke,5);
for(i5=0;i5<120;i5++){
for(j=0;j<5;j++)
aa[j].pads=pads[j];
rot(pads,5);
if(OK()){
printf("---------------------第%d种解---------------------\n",++ans);
for(k=0;k<5;k++)
printf("第%d户: %s人 %s房子 养%s 喝%s 抽%s\n",k+1,GUO[aa[k].guojia],
COL[aa[k].color],PAD[aa[k].pads],DRK[aa[k].drink],SMK[aa[k].smoke]);
}}}}}}
return 0;
}

2007-11-10 21:14
yu_hua
Rank: 2
等 级:论坛游民
帖 子:222
专家分:95
注 册:2006-8-10
得分:0 
运行结果表明:总共有七组可能的解答,具体如下
---------------------第1种解---------------------
第1户: 挪威人 黄房子 养猫 喝水 抽Dunhill
第2户: 丹麦人 蓝房子 养马 喝茶 抽Blends
第3户: 英国人 红房子 养鸟 喝牛奶 抽Pall Mall
第4户: 德国人 绿房子 养鱼 喝咖啡 抽Prince
第5户: 瑞典人 白房子 养狗 喝啤酒 抽BlueMaster
---------------------第2种解---------------------
第1户: 挪威人 绿房子 养鸟 喝咖啡 抽Pall Mall
第2户: 德国人 蓝房子 养猫 喝水 抽Prince
第3户: 英国人 红房子 养马 喝牛奶 抽Blends
第4户: 丹麦人 黄房子 养鱼 喝茶 抽Dunhill
第5户: 瑞典人 白房子 养狗 喝啤酒 抽BlueMaster
---------------------第3种解---------------------
第1户: 挪威人 绿房子 养鸟 喝咖啡 抽Pall Mall
第2户: 德国人 蓝房子 养鱼 喝水 抽Prince
第3户: 英国人 红房子 养马 喝牛奶 抽Blends
第4户: 丹麦人 黄房子 养猫 喝茶 抽Dunhill
第5户: 瑞典人 白房子 养狗 喝啤酒 抽BlueMaster
---------------------第4种解---------------------
第1户: 挪威人 绿房子 养鱼 喝咖啡 抽Blends
第2户: 德国人 蓝房子 养猫 喝水 抽Prince
第3户: 瑞典人 黄房子 养狗 喝牛奶 抽Dunhill
第4户: 英国人 红房子 养马 喝啤酒 抽BlueMaster
第5户: 丹麦人 白房子 养鸟 喝茶 抽Pall Mall
---------------------第5种解---------------------
第1户: 挪威人 绿房子 养鸟 喝咖啡 抽Pall Mall
第2户: 德国人 蓝房子 养猫 喝水 抽Prince
第3户: 瑞典人 白房子 养狗 喝牛奶 抽Blends
第4户: 英国人 红房子 养马 喝啤酒 抽BlueMaster
第5户: 丹麦人 黄房子 养鱼 喝茶 抽Dunhill
---------------------第6种解---------------------
第1户: 挪威人 绿房子 养鸟 喝咖啡 抽Pall Mall
第2户: 德国人 蓝房子 养猫 喝水 抽Prince
第3户: 瑞典人 白房子 养狗 喝牛奶 抽Blends
第4户: 丹麦人 黄房子 养鱼 喝茶 抽Dunhill
第5户: 英国人 红房子 养马 喝啤酒 抽BlueMaster
---------------------第7种解---------------------
第1户: 挪威人 绿房子 养鸟 喝咖啡 抽Pall Mall
第2户: 德国人 蓝房子 养鱼 喝水 抽Prince
第3户: 瑞典人 白房子 养狗 喝牛奶 抽Blends
第4户: 丹麦人 黄房子 养猫 喝茶 抽Dunhill
第5户: 英国人 红房子 养马 喝啤酒 抽BlueMaster
2007-11-10 21:18
yu_hua
Rank: 2
等 级:论坛游民
帖 子:222
专家分:95
注 册:2006-8-10
得分:0 
以下是引用qq95620412在2007-11-11 8:23:28的发言:
2楼的程序好多 goto 啊
goto用多了不好哦
考虑一下不用 goto 啊。

/*------------------------------
爱因斯坦出的逻辑推理难题
C语言程序(已将goto消除)
-------------------------------*/

#include<stdio.h>
#include<math.h>
int aa[5][5];
//aa第0行的意义: 挪威、英国、瑞典、德国、丹麦
//aa第1行的意义: 蓝、黄、绿、红、白
//aa第2行的意义: 牛奶、咖啡、啤酒、茶、水
//aa第3行的意义: 猫、狗、马、鸟、鱼
//aa第4行的意义: Blends、BlueMaster、Dunhill、Pall Mall、Prince
//aa[i][j]的意义:该人或物所属房间号(注意思路已经有了改变)
char*msg[][5]={"挪威人","英国人","瑞典人","德国人","丹麦人",
"蓝房子","黄房子","绿房子","红房子","白房子",
"喝牛奶","喝咖啡","喝啤酒","喝茶 ","喝水 ",
"养猫","养狗","养马","养鸟","养鱼","抽Blends",
"抽BlueMaster","抽Dunhill","抽Pall Mall","抽Prince"};
char guoji[4]={2,3,4,5};
char color[4]={1,3,4,5};
char drink[4]={1,2,4,5};
char pads[5]={1,2,3,4,5};
char smoke[]={1,2,3,4,5};

int OK(void)
{
if( (aa[1][1]==aa[4][2]) //黄房 抽Dunhill
&&(aa[2][1]==aa[1][2]) //绿房 喝咖啡
&&(aa[0][1]==aa[1][3]) //红房 英国人
&&(aa[2][2]==aa[4][1]) //喝啤酒者 抽BlueMaster
&&(aa[3][3]==aa[4][3]) //养鸟者 抽PallMal
&&(aa[0][2]==aa[3][1]) //瑞典人 养狗
&&(aa[0][3]==aa[4][4]) //德国人 抽Prince
&&(aa[0][4]==aa[2][3]) //丹麦人 喝茶
&&(abs(aa[4][0]-aa[3][0])==1)// 抽Blends者与养猫人邻居
&&(abs(aa[4][0]-aa[2][4])==1)// 抽Blends者与喝水人邻居
&&(abs(aa[3][2]-aa[4][2])==1)// 抽Dunhil者与养马人邻居
) return 1;
else
return 0;
}

int rot(char a[],int n) //全排列
{ int i,j,k,t;
for(k=n-1;k>0;k--)
if(a[k-1]<a[k])break;
if(k==0)
{ for(i=0,j=n-1;i<j;i++,j--)
{ char t=a[i];
a[i]=a[j];
a[j]=t;
}
return 0;
}
t=a[k-1];i=k;
for(j=k+1;j<n;j++)
if(t<a[j]&&a[j]<a[i])i=j;
a[k-1]=a[i];a[i]=t;
for(i=k;i<n-1;i++)
for(j=k;j<n-1+k-i;j++)
if(a[j]>a[j+1])
{ t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
return 1;
}

int main()
{
int i1,i2,i3,i4,i5,i,j,k,ans=0;
aa[0][0]=1; //表示挪威人住在1号房
aa[1][0]=2; //表示蓝色房子是2号房
aa[2][0]=3; //表示喝牛奶者在3号房
for(i1=0;i1<24;i1++)
{ for(j=0;j<4;j++)aa[1][j+1]=color[j];
rot(color,4);
if(aa[1][2]<aa[1][4]) //绿房在白房的左边
for(i2=0;i2<24;i2++)
{ for(j=0;j<4;j++)aa[0][j+1]=guoji[j];
rot(guoji,4);
for(i3=0;i3<24;i3++)
{ for(j=0;j<4;j++)aa[2][j+1]=drink[j];
rot(drink,4);
for(i4=0;i4<120;i4++)
{ for(j=0;j<5;j++)aa[3][j]=pads[j];
rot(pads,5);
for(i5=0;i5<120;i5++)
{ for(j=0;j<5;j++)aa[4][j]=smoke[j];
rot(smoke,5);
if(OK())
{ printf("--------------第%d组解如下--------------------\n",++ans);
for(k=1;k<=5;k++)
{ printf("第%d户: ",k);
for(i=0;i<=4;i++)
for(j=0;j<=4;j++)
if(aa[i][j]==k)printf("%s ",msg[i][j]);
printf("\n");
}
}
}
}
}
}
}
printf("=============================================\n");
return 0;
}

2007-11-11 13:02
yu_hua
Rank: 2
等 级:论坛游民
帖 子:222
专家分:95
注 册:2006-8-10
得分:0 

/*------------------------------
怎样让爱因斯坦出的逻辑
推理难题只有唯一的解?
见下文中的红色粗体字
-------------------------------*/
#include<stdio.h>
#include<math.h>
int aa[5][5];
//aa第0行的意义: 挪威、英国、瑞典、德国、丹麦
//aa第1行的意义: 蓝、黄、绿、红、白
//aa第2行的意义: 牛奶、咖啡、啤酒、茶、水
//aa第3行的意义: 猫、狗、马、鸟、鱼
//aa第4行的意义: Blends、BlueMaster、Dunhill、Pall Mall、Prince
//aa[i][j]的意义:该人或物所属房间号
char*msg[][5]={"挪威人", "英国人", "瑞典人", "德国人", "丹麦人",
"蓝房子", "黄房子", "绿房子", "红房子", "白房子",
"喝牛奶", "喝咖啡", "喝啤酒", "喝茶 ", "喝水 ",
"养猫", "养狗", "养马", "养鸟", "养鱼",
"抽Blends","抽BlueMaster","抽Dunhill","抽Pall Mall","抽Prince"};
char guoji[4]={2,3,4,5};
char color[4]={1,3,4,5};
char drink[4]={1,2,4,5};
char pads[5]={1,2,3,4,5};
char smoke[]={1,2,3,4,5};

int OK(void)
{
if( (aa[1][1]==aa[4][2]) //黄房 抽Dunhill
&&(aa[2][1]==aa[1][2]) //喝咖啡者 绿房
&&(aa[0][1]==aa[1][3]) //英国人 红房
&&(aa[2][2]==aa[4][1]) //喝啤酒者 抽BlueMaster
&&(aa[3][3]==aa[4][3]) //养鸟者 抽PallMal
&&(aa[0][2]==aa[3][1]) //瑞典人 养狗
&&(aa[0][3]==aa[4][4]) //德国人 抽Prince
&&(aa[0][4]==aa[2][3]) //丹麦人 喝茶
&&(abs(aa[4][0]-aa[3][0])==1)// 抽Blends者与养猫人邻居
&&(abs(aa[4][0]-aa[2][4])==1)// 抽Blends者与喝水人邻居
&&(abs(aa[4][2]-aa[3][2])==1)// 抽Dunhil者与养马人邻居
) return 1;
else
return 0;
}

int rot(char a[],int n) //全排列
{ int i,j,k,t;
for(k=n-1;k>0;k--)
if(a[k-1]<a[k])break;
if(k)
{
t=a[k-1];i=k;
for(j=k+1;j<n;j++)
if(t<a[j]&&a[j]<a[i])i=j;
a[k-1]=a[i];a[i]=t;
for(i=k;i<n-1;i++)
for(j=k;j<n-1+k-i;j++)
if(a[j]>a[j+1])
{ t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
else
for(i=0,j=n-1;i<j;i++,j--)
{ t=a[i];
a[i]=a[j];
a[j]=t;
}
return k;
}

int main()
{
int i,j,k,ans=0;
aa[0][0]=1; //表示挪威人住在1号房
aa[1][0]=2; //表示蓝色房子是2号房
aa[2][0]=3; //表示喝牛奶者在3号房
do
{ for(j=0;j<4;j++)aa[0][j+1]=guoji[j];//国籍
do
{ for(j=0;j<4;j++)aa[1][j+1]=color[j];//颜色
if(aa[1][4]-aa[1][2]==1)//绿房应为白房的左邻,而不能仅仅是在白房的左边
do
{ for(j=0;j<4;j++)aa[2][j+1]=drink[j];//饮料
do
{ for(j=0;j<5;j++)aa[3][j]=pads[j];//宠物
do
{ for(j=0;j<5;j++)aa[4][j]=smoke[j];//香烟
if(OK())
{
printf("--------------第%d组解如下--------------------\n",++ans);
for(k=1;k<=5;k++)
{
printf("第%d户: ",k);
for(i=0;i<=4;i++)
for(j=0;j<=4;j++)
if(aa[i][j]==k)printf("%s ",msg[i][j]);
printf("\n");
}
}
}while(rot(smoke,5));//五种香烟全排列
}while(rot(pads,5)); //五种宠物全排列
}while(rot(drink,4)); //咖啡,啤酒,茶,水全排列
}while(rot(color,4)); //黄色,绿色,红色,白色全排列
}while(rot(guoji,4)); //英国,瑞典,德国,丹麦全排列
printf("=============================================\n");
return 0;
}

2007-11-12 06:18
yu_hua
Rank: 2
等 级:论坛游民
帖 子:222
专家分:95
注 册:2006-8-10
得分:0 
用 VC6.0 运行结果如下:

--------------第1组解如下--------------------
第1户: 挪威人 黄房子 喝水 养猫 抽Dunhill
第2户: 丹麦人 蓝房子 喝茶 养马 抽Blends
第3户: 英国人 红房子 喝牛奶 养鸟 抽Pall Mall
第4户: 德国人 绿房子 喝咖啡 养鱼 抽Prince
第5户: 瑞典人 白房子 喝啤酒 养狗 抽BlueMaster
=============================================
Press any key to continue

这样一来,唯一的结论就是:德国人养鱼
2007-11-12 06:23
yu_hua
Rank: 2
等 级:论坛游民
帖 子:222
专家分:95
注 册:2006-8-10
得分:0 

/*------------------------------
爱因斯坦逻辑推理难题
C语言程序设计完美版
-------------------------------*/
#include<stdio.h>
#include<math.h>
char guoji[]={1/*挪威人住1号房*/,2,3,4,5},
color[]={2/*蓝房子是2号房*/,1,3,4,5},
drink[]={3/*喝牛奶者3号房*/,1,2,4,5},
pads[ ]={1,2,3,4,5},
smoke[]={1,2,3,4,5},
*aa[5]={guoji,color,drink,pads,smoke},
*msg[]={"挪威人", "英国人", "瑞典人", "德国人", "丹麦人",
"蓝房子", "黄房子", "绿房子", "红房子", "白房子",
"喝牛奶", "喝咖啡", "喝啤酒", "喝茶 ", "喝水 ",
"养猫", "养狗", "养马", "养鸟", "养鱼" ,
"抽Blends","抽BlueMaster","抽Dunhill","抽Pall Mall","抽Prince"};
int OK(void)
{
if( (color[1]==smoke[2]) //住黄房者 抽Dunhill
&&(drink[1]==color[2]) //喝咖啡者 住绿房
&&(guoji[1]==color[3]) //英国人 住红房
&&(drink[2]==smoke[1]) //喝啤酒者 抽BlueMaster
&&(pads[3]==smoke[3]) //养鸟者 抽PallMal
&&(guoji[2]==pads[1]) //瑞典人 养狗
&&(guoji[3]==smoke[4]) //德国人 抽Prince
&&(guoji[4]==drink[3]) //丹麦人 喝茶
&&(abs(smoke[0]-pads[0])==1)// 抽Blends者与养猫人邻居
&&(abs(smoke[0]-drink[4])==1)// 抽Blends者与喝水人邻居
&&(abs(smoke[2]-pads[2])==1)// 抽Dunhil者与养马人邻居
&&((color[2]-color[4])== -1)// 绿房是白房的左邻
) return 1;
else
return 0;
}

//全排列(要求n个元素互异,且最初n个元素已按升序排列好)
int rot(char a[],int n)
{ int i,j,k,t;
for(k=n-1;k>0;k--)
if(a[k-1]<a[k])break;
if(k)
{
t=a[k-1];i=k;
for(j=k+1;j<n;j++)
if(t<a[j]&&a[j]<a[i])i=j;
a[k-1]=a[i];a[i]=t;
for(i=k;i<n-1;i++)
for(j=k;j<n-1+k-i;j++)
if(a[j]>a[j+1])
{ t=a[j];
a[j]=a[j+1];
a[j+1]=t;
}
}
else
for(i=0,j=n-1;i<j;i++,j--)
{ t=a[i];
a[i]=a[j];
a[j]=t;
}
return k;
}

int main()
{
int i,j,k,ans=0;
do
{
do
{
do
{
do
{
do
{
if(OK())
{
printf("--------------第%d组解如下--------------------\n",++ans);
for(k=1;k<=5;k++)
{
printf("第%d户: ",k);
for(i=0;i<=4;i++)
for(j=0;j<=4;j++)
if(aa[i][j]==k)printf("%s ",msg[5*i+j]);
printf("\n");
}
}
}while(rot(smoke,5)); //五种香烟全排列
}while(rot(pads,5)); //五种宠物全排列
}while(rot(drink+1,4));//咖啡,啤酒,茶,水全排列
}while(rot(color+1,4));//黄色,绿色,红色,白色全排列
}while(rot(guoji+1,4)); //英国,瑞典,德国,丹麦全排列
printf("=============================================\n");
return 0;
}

/** 运行结果
--------------第1组解如下--------------------
第1户: 挪威人 黄房子 喝水 养猫 抽Dunhill
第2户: 丹麦人 蓝房子 喝茶 养马 抽Blends
第3户: 英国人 红房子 喝牛奶 养鸟 抽Pall Mall
第4户: 德国人 绿房子 喝咖啡 养鱼 抽Prince
第5户: 瑞典人 白房子 喝啤酒 养狗 抽BlueMaster
=============================================
**/

2007-11-12 11:54
yu_hua
Rank: 2
等 级:论坛游民
帖 子:222
专家分:95
注 册:2006-8-10
得分:0 
以下是引用yixiaowz在2007-11-12 14:47:07的发言:
有难度啊,能否把思路解释下啊,谢了先!!!

  下面我针对发表在12楼的“完美版”程序作些解释。
  首先,讲一下总体思路:本题总共有5户人家,每户5个信息(国籍、房子颜色、宠物、饮料、香烟牌子)
因此总共有25样东西需要落实它们的“房号”,房号的取值范围是1、2、3、4、5。然而,依题意,有3样东
西的房号是已知的,即:挪威人住1号房、2号房为蓝色、喝奶的住3号房。因此我们面临的任务就相当于求解
含22个未知数的方程组。下面介绍我给这些未知数起的名字吧。
  由于房号是不大于五的整数,所以我定义了一堆字符型数组来表示这25样东西。具体如下:
1。数组char guoji[5]映射户主的国籍。其中guoji[0]代表挪威人,因为他住1号房,所以guoji[0]元素的
  初值是1,guoji[1]代表英国人、guoji[2]代表瑞典人、guoji[3]代表德国人、guoji[4]代表丹麦人。
  那么我凭什么将它们顺序地赋予2、3、4、5的初值呢?难道2号房真的住着英国人………5号房真的住着
  丹麦人?非也!但有一点可以肯定,2、3、4、5号房子里住着除挪威而外的四国人。后面的程序中将要
  对这四个房号全排列的24种情况逐一进行测试,看看哪种情况符合题目规定的约束条件。
2。数组char color[5]映射房子的颜色。其中color[0]代表蓝色,因已知2号房涂蓝色,所以color[0]元素
  初值是2,color[1]代表黄、color[2]代表绿、color[3]代表红、color[4]代表白色。那么我凭什么将
  它们顺序地赋予1、3、4、5的初值呢?难道1号房涂黄色、3号房涂绿色………5号房涂白?非也!但是
可以肯定,1、3、4、5号房的颜色不外乎黄、绿、红、白。后面的程序中将要对这四个房号全排列的24
  种情况逐一进行试验,看看哪种情况符合题目规定的约束条件。
3。数组char drink[5]对应五种饮料。其中drink[0]代表牛奶,因为3号房主喝牛奶,所以drink[0]元素的
  初值是3,drink[1]代表咖啡、drink[2]代表啤酒、drink[3]代表茶、drink[4]代表水。那么我凭什么
  将它们顺序地赋予1、2、4、5的初值呢?难道1号房主喝咖啡………5号房主喝水?非也!但是可以肯定
1、2、4、5号房主喝的不外乎咖啡、啤酒、茶、水。后面的程序中将要对这四个房号全排列的24种情况
  逐一进行试验,看看哪种情况符合题目规定的约束条件。
4。数组char pads[5]对应五种宠物。pads[0]代表猫,pads[1]代表狗、pads[2]代表马、pads[3]代表鸟、
  pads[4]代表鱼。那么我凭什么将它们顺序地赋予1、2、3、4、5的初值呢?难道1号房主养猫………5号
  房主养鱼?非也!但是可以肯定五名房主养的不外乎猫、狗、马、鸟、鱼。后面的程序中将要对这五个
  房号全排列的120种情况逐一进行试验,看看哪种情况符合题目规定的约束条件。
5。数组char smoke[5]对应五种香烟。smoke[0]代表Blends牌香烟,smoke[1]代表BlueMaster、smoke[2]
  代表Dunhill、smoke[3]代表Pall Mall、smoke[4]代表Prince。那么凭什么将它们顺序地赋予1、2、3、
  4、5的初值呢?难道1号房主抽Blends烟………5号房主抽Prince烟?非也!但可以肯定,五名房主抽的
  不外乎那五种品牌的香烟。后面的程序中将要对这五个房主全排列的120种可能的抽烟情况逐一试验,
  看看哪种情况符合题目规定的约束条件。

  由此可见,我设计的程序将要依赖计算机的高速度,疯狂地对24×24×24×120×120种可能情况逐一地
测试它们是否满足全部约束条件。于是我的程序共有3个函数:main( )完成“五重循环”并负责把满足全部
约束条件的合格解在屏幕上显示出来。OK()负责检测每组(22个)数据是否满足约束条件,仅当满足全部约束
条件时才返回1,否则返回0。rot()是全排列生成函数,个人觉得这个程序段是最出彩的。
  应当指出,12楼的代码虽然比较短,但运行速度比较慢。如果要提速,最明显的方法就是把OK()判断函
数中开头八个“==”关系直接用起来,从而把未知数从22个降为14个!但代码的短小精悍特性将不复存在。

[此贴子已经被作者于2007-11-12 21:29:00编辑过]

2007-11-12 19:07
yu_hua
Rank: 2
等 级:论坛游民
帖 子:222
专家分:95
注 册:2006-8-10
得分:0 
以下是引用coding在2007-11-12 21:09:27的发言:

这个题目如果用进制算的话,很简单的

愿闻其详。烦您不吝赐教。

2007-11-12 21:18
yu_hua
Rank: 2
等 级:论坛游民
帖 子:222
专家分:95
注 册:2006-8-10
得分:0 
/*--------------------------------------------
    本人用C语言编写的破解难题的程序(完美版)
----------------------------------------------*/
#include<stdio.h>
#include<math.h>
int aa[5][5];
//aa第0行的意义: 挪威、英国、瑞典、德国、丹麦
//aa第1行的意义: 蓝、黄、绿、红、白
//aa第2行的意义: 牛奶、咖啡、啤酒、茶、水
//aa第3行的意义: 猫、狗、马、鸟、鱼
//aa第4行的意义: Blends、BlueMaster、Dunhill、Pall Mall、Prince
//aa[i][j]的意义:该人或物所属房间号
char*msg[][5]={"挪威人","英国人","瑞典人","德国人","丹麦人",
               "蓝房子","黄房子","绿房子","红房子","白房子",
               "喝牛奶","喝咖啡","喝啤酒","喝茶  ","喝水  ",
               "养猫","养狗","养马","养鸟","养鱼","抽Blends",
               "抽BlueMaster","抽Dunhill","抽Pall Mall","抽Prince"};
char guoji[4]={2,3,4,5};
char color[4]={1,3,4,5};
char drink[4]={1,2,4,5};
char pads[5]={1,2,3,4,5};
char smoke[]={1,2,3,4,5};

int OK(void)
{
   if( (aa[1][1]==aa[4][2]) //黄房     抽Dunhill
     &&(aa[2][1]==aa[1][2]) //绿房     喝咖啡
     &&(aa[0][1]==aa[1][3]) //红房     英国人
     &&(aa[2][2]==aa[4][1]) //喝啤酒者 抽BlueMaster
     &&(aa[3][3]==aa[4][3]) //养鸟者   抽PallMal
     &&(aa[0][2]==aa[3][1]) //瑞典人   养狗
     &&(aa[0][3]==aa[4][4]) //德国人   抽Prince
     &&(aa[0][4]==aa[2][3]) //丹麦人   喝茶
     &&(abs(aa[4][0]-aa[3][0])==1)//   抽Blends者与养猫人邻居
     &&(abs(aa[4][0]-aa[2][4])==1)//   抽Blends者与喝水人邻居
     &&(abs(aa[3][2]-aa[4][2])==1)//   抽Dunhil者与养马人邻居
     )  return 1;
     else
        return 0;
}

int rot(char a[],int n) //全排列
{   int i,j,k,t;
    for(k=n-1;k>0;k--)
       if(a[k-1]<a[k])break;
    if(k==0)
    {  for(i=0,j=n-1;i<j;i++,j--)
       { char t=a[i];
           a[i]=a[j];
           a[j]=t;
       }
       return 0;
    }
    t=a[k-1];i=k;
    for(j=k+1;j<n;j++)
      if(t<a[j]&&a[j]<a[i])i=j;
    a[k-1]=a[i];a[i]=t;
    for(i=k;i<n-1;i++)
      for(j=k;j<n-1+k-i;j++)
        if(a[j]>a[j+1])
        {  t=a[j];
           a[j]=a[j+1];
           a[j+1]=t;
        }
    return 1;
}

int main()
{
    int i1,i2,i3,i4,i5,i,j,k,ans=0;
    aa[0][0]=1; //表示挪威人住在1号房
    aa[1][0]=2; //表示蓝色房子是2号房
    aa[2][0]=3; //表示喝牛奶者在3号房
    for(i1=0;i1<24;i1++)
    {   for(j=0;j<4;j++)aa[1][j+1]=color[j];
        rot(color,4);
        if(aa[1][2]<aa[1][4]) //绿房在白房的左边
        for(i2=0;i2<24;i2++)
        {   for(j=0;j<4;j++)aa[0][j+1]=guoji[j];
            rot(guoji,4);
            for(i3=0;i3<24;i3++)
            {   for(j=0;j<4;j++)aa[2][j+1]=drink[j];
                rot(drink,4);
                for(i4=0;i4<120;i4++)
                {   for(j=0;j<5;j++)aa[3][j]=pads[j];
                    rot(pads,5);
                    for(i5=0;i5<120;i5++)
                    {   for(j=0;j<5;j++)aa[4][j]=smoke[j];
                        rot(smoke,5);
                        if(OK())
                        {  printf("--------------第%d组解如下--------------------\n",++ans);
                           for(k=1;k<=5;k++)
                           {   printf("第%d户: ",k);
                               for(i=0;i<=4;i++)
                                 for(j=0;j<=4;j++)
                                   if(aa[i][j]==k)printf("%s ",msg[i][j]);
                               printf("\n");
                           }
                        }
                    }
                }
            }
        }
    }
    printf("=============================================\n");
    return 0;
}

/**
--------------第1组解如下--------------------
第1户: 挪威人 黄房子 喝水   养猫 抽Dunhill
第2户: 丹麦人 蓝房子 喝茶   养马 抽Blends
第3户: 英国人 红房子 喝牛奶 养鸟 抽Pall Mall
第4户: 德国人 绿房子 喝咖啡 养鱼 抽Prince
第5户: 瑞典人 白房子 喝啤酒 养狗 抽BlueMaster
--------------第2组解如下--------------------
第1户: 挪威人 绿房子 喝咖啡 养鱼 抽Blends
第2户: 德国人 蓝房子 喝水   养猫 抽Prince
第3户: 瑞典人 黄房子 喝牛奶 养狗 抽Dunhill
第4户: 英国人 红房子 喝啤酒 养马 抽BlueMaster
第5户: 丹麦人 白房子 喝茶   养鸟 抽Pall Mall
--------------第3组解如下--------------------
第1户: 挪威人 绿房子 喝咖啡 养鸟 抽Pall Mall
第2户: 德国人 蓝房子 喝水   养猫 抽Prince
第3户: 英国人 红房子 喝牛奶 养马 抽Blends
第4户: 丹麦人 黄房子 喝茶   养鱼 抽Dunhill
第5户: 瑞典人 白房子 喝啤酒 养狗 抽BlueMaster
--------------第4组解如下--------------------
第1户: 挪威人 绿房子 喝咖啡 养鸟 抽Pall Mall
第2户: 德国人 蓝房子 喝水   养鱼 抽Prince
第3户: 英国人 红房子 喝牛奶 养马 抽Blends
第4户: 丹麦人 黄房子 喝茶   养猫 抽Dunhill
第5户: 瑞典人 白房子 喝啤酒 养狗 抽BlueMaster
--------------第5组解如下--------------------
第1户: 挪威人 绿房子 喝咖啡 养鸟 抽Pall Mall
第2户: 德国人 蓝房子 喝水   养猫 抽Prince
第3户: 瑞典人 白房子 喝牛奶 养狗 抽Blends
第4户: 丹麦人 黄房子 喝茶   养鱼 抽Dunhill
第5户: 英国人 红房子 喝啤酒 养马 抽BlueMaster
--------------第6组解如下--------------------
第1户: 挪威人 绿房子 喝咖啡 养鸟 抽Pall Mall
第2户: 德国人 蓝房子 喝水   养鱼 抽Prince
第3户: 瑞典人 白房子 喝牛奶 养狗 抽Blends
第4户: 丹麦人 黄房子 喝茶   养猫 抽Dunhill
第5户: 英国人 红房子 喝啤酒 养马 抽BlueMaster
--------------第7组解如下--------------------
第1户: 挪威人 绿房子 喝咖啡 养鸟 抽Pall Mall
第2户: 德国人 蓝房子 喝水   养猫 抽Prince
第3户: 瑞典人 白房子 喝牛奶 养狗 抽Blends
第4户: 英国人 红房子 喝啤酒 养马 抽BlueMaster
第5户: 丹麦人 黄房子 喝茶   养鱼 抽Dunhill
=============================================
**/
2007-11-22 21:07



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-185111-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.710049 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved