|
楼主 |
发表于 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' ¦¦ 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;} |
|