54.迷语博士的难题(2)
两面族是荒岛上的一个新民族,他们的特点是说话真一句假一句且真假交替。如果第一句为真,则第二句是假的;如果第一句为假的,则第二句就是真的,但是第一句是真是假没有规律。
迷语博士遇到三个人,知道他们分别来自三个不同的民族:诚实族、说谎族和两面族。三人并肩站在博士前面。
博士问左边的人:“中间的人是什么族的?”,左边的人回答:“诚实族的”。
博士问中间的人:“你是什么族的?”,中间的人回答:“两面族的”。
博士问右边的人:“中间的人究竟是什么族的?”,右边的人回答:“说谎族的”。
请问:这三个人都是哪个民族的?
*问题分析与算法设计
这个问题是两面族问题中最基本的问题,它比前面只有诚实族和说谎族的问题要复杂。解题时要使用变量将这三个民族分别表示出来。
令:变量A=1表示:左边的人是诚实族的(用C语言表示为A);
变量B=1表示:中间的人是诚实族的(用C语言表示为B);
变量C=1表示:右边的人是诚实族的(用C语言表示为C);
变量AA=1表示:左边的人是两面族的(用C语言表示为AA);
变量BB=1表示:中间的人是两面族的(用C语言表示为BB);
变量CC=1表示:右边的人是两面族的(用C语言表示为CC);
则左边的人是说谎族可以表示为:A!=1且AA!=1 (不是诚实族和两面族的人)
用C语言表示为:!A&&!AA
中间的人是说谎族可以表示为:B!=1且BB!=1
用C语言表示为:!B&&!BB
右边的人是说谎族可以表示为:C!=0且CC!=1
用C语言表示为:!C&&!CC
根据题目中“三人来自三个民族”的条件,可以列出:
a+aa!=2&&b+bb!=2&&c+cc!=2 且 a+b+c==1&&aa+bb+cc==1
根据左边人的回答可以推出:若他们是诚实族,则中间的人也是诚实族;若他不是诚实族,则中间的人也不是诚实族。以上条件可以表示为:
c&&!b&&!bb||(!c&&!cc)&&(b||bb)||!c&&cc
将全部逻辑条件联合在一起,利用穷举的方法求解,凡是使上述条件同时成立的变量取值就是题目的答案。
*程序与程序注释
#include<stdio.h>
void main()
{
int a,b,c,aa,bb,cc;
for(a=0;a<=1;a++) /*穷举全部情况*/
for(b=0;b<=1;b++)
for(c=0;c<=1;c++)
for(aa=0;aa<=1;aa++)
for(bb=0;bb<=1;bb++)
for(cc=0;cc<=1;cc++)
if(a+aa!=2&&b+bb!=2&&c+cc!=2&& /*判断逻辑条件*/
a+b+c==1&&aa+bb+cc==1 &&
(a&&!aa&&b&&!bb||!a&&!b)&&
!b &&
(c&&!b&&!bb||(!c&&!cc)&&(b||bb)||!c&cc))
{
printf("The man stand on left is a %s.\n",
aa?"double--dealer":(a?"honest":"lier"));
printf("The man stand on left is a %s.\n",
bb?"double--dealer":(b?"honest":"lier"));
printf("The man stand on left is a %s.\n",
cc?"double--dealer":(c?"honest":"lier"));
/*输出最终的推理结果*/
}
}
*运行结果
The man stand on left is a double--dealer. (左边的人是两面族的)
The man stand on center is a lier. (中间的人是说谎族的)
The man stand on right is a honest. (右边的人是诚实族的)
*思考题
迷语博士遇到三个人,便问第一个人:“你是什么族的?”,回答:“诚实族的。”问第二个人:“你是什么族的?”,答:“说谎族的。”博士又问第二个人:“第一个人真的是诚实族的吗?”,答:“是的。”问第三个人:“你是什么族的?”,答:“诚实族的。”博士又问第三个人:“第一个人是什么族的?”,答:“两面族的。”
请判断这个人到底是哪个民族的?
(答案:第一个人是诚实族的,第二个人是两面族的,第三人是说谎族。)
正文
54.迷语博士的难题(2)2005-09-10 15:20:00
【评论】 【打印】 【字体:大 中 小】 本文链接:http://blog.pfan.cn/xiangyu/1704.html
阅读(5626) | 评论(1)
版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!
评论