逻辑推理与判断(谜语博士的难题)

谜博士的难题(1)

诚实族与说谎族是来自两个荒岛的不同民族,诚实族的人永远说真话,说谎族的人永远说假话。

谜语博士遇到三个人,他们可能是来自诚实族或者是说谎族的。博士问了他们一个问题:

问第一个人:“你们是什么族?”,答“我们当中有两个来自诚实族。”第二个人说“不要胡说,我们三个人中只有一个诚实族的。”第三个人听了第二个人的话后说“对,就是只有一个诚实族的。”

根据他们的回答判断它们分别是哪个组的。

问题分析与算法设计:

假设三个人分别为A、B、C,若说谎其值为0,若诚实其值为1.

第一个人: a&&a+b+c==2 || !a&&a+b+c!=2

第二个人: b&&a+b+c==1 || !a&&a+b+c!=1

第三个人: c&&a+b+c==1 || !a&&a+b+c!=1

利用穷举法可以很容易的推断出正确结果

程序设计与注释:

#include <stdio.h>

int main()
{
    int a;
    int b;
    int c;

    for(a = 0;a <= 1;a++)              /*穷举每个人是说谎还是诚实的全部情况*/
    {                                                        /*诚实:0        说谎:1 */
        for(b = 0;b <= 1;b++)
        {
            for(c = 0;c <= 1;c++)
            {
                if((a && a + b + c == 2 || !a && a + b + c != 2)                      /*判断是否满足题意*/
                   && (b && a + b + c == 1 || !b && a + b + c != 1)
                   && (c && a + b + c == 1 || !c && a + b + c != 1))
                {
                    printf("A is a %s. \n",a ? "honest" : "lier");                       /*输出判断结果*/
                    printf("B is a %s. \n",b ? "honest" : "lier");
                    printf("C is a %s. \n",c ? "honest" : "lier");
                }
            }
        }
    }

    return 0;
}

谜博士的难题(2)

两面族是荒岛上的一个新民族说话真一句假一句且真假交替。如果第一句为真,第二句就为假;如果第一句为假,第二句就为真。但第一句是真是假没有规律。

迷博士遇到三个人,直到他们来自三个不同的民族。三个人并肩站在博士面前。

博士问左边的人:“中间的人是什么族?”,左边人回答:“诚实族”。

博士问中间的人:“你是什么族的?”,中间人回答:“两面族”

博士问右边的人:“中间的人究竟是什么族的?”,右边人回答:“说谎族”

请问:三个人分别是哪个民族

问题分析与算法设计:

解题时要使用变量将这三个民族分别表示出来

变量A=1,表示:左边的人是诚实族的

变量B=1,表示:中间的人是诚实族的

变量C=1,表示:右边的人是诚实族的

变量AA=1表示:左边的人是两面族的

变量BB=1表示:中间的人是两面族的

变量CC=1表示:右边的人是两面族的

则左边的人是说谎族的可以表示为:A!=1且AA!=1  用C语言表示为!A&&!AA

则中间的人是说谎族的可以表示为:B!=1且BB!=1  用C语言表示为!B&&!BB

则右边的人是说谎族的可以表示为:C!=1且CC!=1  用C语言表示为!C&&!CC

根据三个人来自三个民族的条件可知:

a+aa!=2 && b+bb!=2 && c+cc!=2  且a+b+c ==1 && a+b+c ==1

由左人回答推出:a && !aa && b && !bb || !a && !b

有中间人回答推出:!b

由右人回答推出:a && !b && !bb || (!c && !cc) && (b || bb) || !c && cc

程序设计

#include <stdio.h>

int main()
{
    int a;
    int b;
    int c;
    int aa;
    int bb;
    int 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 center is a %s. \n",
                                        bb ? "double-dealer" : (b ? "honest" : "lier"));
                                printf("The man stand on right is a %s. \n",
                                        cc ? "double-dealer" : (c ? "honest" : "lier"));
                            }
                        }
                    }
                }
            }
        }
    }

    return 0;
}

 

 

 

 

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值