偷盗者问题。甲乙丙丁四个嫌疑犯,只有一个是偷盗者。在审讯中,四人都有可能说真话或假话

通过逻辑推理和编码验证,解析甲乙丙丁四人陈述中的真实小偷身份,展示了一种枚举和验证真伪的算法解决方案。

偷盗者问题。甲乙丙丁四个嫌疑犯,只有一个是偷盗者。在审讯中,四人都有可能说真话或假话。

甲:乙没偷,丁偷。

乙:我没偷,丙偷。

丙:甲没偷,乙偷。

丁:我没偷。

问谁是小偷。

思路

由于只有一个人是小偷,所以可以枚举四个人分别是小偷,然后再看他们的说法在当前的情况下是否有矛盾。

由于四人都有可能说真话或者假话,所以对他们说的话也要枚举,分别尝试每个人说的是真话或者是假话。

代码

以下代码中a b c d分别代表甲乙丙丁,函数[A/B/C/D][T/F]()即对他们的说法进行判断

#include<stdio.h>
#define FOR(i,a,b) for(int i=a;i<=b;++i)
int a, b, c, d;
typedef int(*FUNC)();
#define JF(X) int X##F(){return !X##T();}
int AT(){ return b == 0 && d == 1; }
int BT(){ return b == 0 && c == 1; }
int CT(){ return a == 0 && b == 1; }
int DT(){ return d == 0; }
JF(A)
JF(B)
JF(C)
JF(D)
int main()
{
    for (int i = 1; i <= 4; ++i)
    {
        a = i == 1 ? 1 : 0;
        b = i == 2 ? 1 : 0;
        c = i == 3 ? 1 : 0;
        d = i == 4 ? 1 : 0;
        FUNC f1[] = { AF, AT };
        FUNC f2[] = { BF, BT };
        FUNC f3[] = { CF, CT };
        FUNC f4[] = { DF, DT };
        FOR(d1, 0, 1)
        FOR(d2, 0, 1)
        FOR(d3, 0, 1)
        FOR(d4, 0, 1)
        {
            if (f1[d1]() && f2[d2]() && f3[d3]() && f4[d4]())
            {
                printf("小偷:%c\n",'a' + i - 1);
                printf("真话or假话:\n");
                printf("a b c d\n");
                printf("%d %d %d %d\n", d1, d2, d3, d4);
                puts("-----------");
            }
        }
    }
}

运行结果:

可以发现,其实甲乙丙丁都有可能是小偷。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值