题目内容
题目日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个嫌疑犯的一个。
以下为4个嫌疑犯的供词:
A说:不是我。
B说:是C。
C说:是D。
D说:C在胡说
已知3个人说了真话,1个人说的是假话。
现在请根据这些信息,写一个程序来确定到底谁是凶手。
题目分析
这是一道经典的逻辑推理问题,如果我们从数学的角度来分析,就是要寻找矛盾点和相同点进而做出假设分析,在假设的前提下来推理。
例如 C和D两个选手有一处矛盾点就是:D是否是凶手,我们可以从这个点进行突破,假设D是凶手这个是对的,那我们就根据A和B的话来判断;假设D是凶手这个是错的,同理推测
如果我们从编程的角度来分析,我们就要先知道总共的可能性,把每一种可能考虑到。
思路一
这个的思路就是和我之前写的那个逻辑类型题1中的跳水运动员预测比赛结果排名次问题一样。每个abcd四个人要么为0,要么为1,通过四个循环得到所有的结果,
然后我们通过这四个人说的话将其翻译为代码,然后有一个人说谎那么他说的话得到的就是0;
其他人说的是真话得到的答案为1,那么四个表达式相加就为3
但是千万不能忘了凶手只有一个那么四个值相加就只能为1最后再通过f语句判断哪一个是1由此就能得到谁是凶手了。
思路二
每次假设一个人说了谎,4次循环
然后cd说话矛盾
fd为1则表示矛盾任然存在
为0则表示矛盾消失,
那么当在这四次循环中有谁满足了只有一个凶手且fd为0则就抓住了凶手。
代码展示
思路一
#include<stdio.h> int main() { int a = 0, b = 0, c = 0, d = 0; for (a = 0; a <= 1; a++) { for (b = 0; b <= 1; b++) { for (c = 0; c <= 1; c++) { for (d = 0; d <= 1; d++) {//上面的代码 if ((a != 1) + (c == 1) + (d == 1) + (d != 1)==3) { if (a + b + c + d == 1) { if (a == 1) printf("a为凶手"); else if (b == 1) printf("b为凶手"); else if (c == 1) printf("c为凶手"); else printf("d是凶手"); } } } } } return 0; } }
思路二
#include<stdio.h> int main() { int a=0, b=0, c=0, d=0, fd=0; int i = 0; for (i = 0; i < 4; i++) { if (i == 0)//假设a说的就是假话 { a = 1; c = 1; d = 0; fd = 1; } if (i == 1)//假设b说的是假话 { a = 0; c = 0; d = 0; fd = 1; } if (i == 2)//假设c说的是假话 { a = 0; c = 1; d = 0; fd = 0; } if (i == 3)//假设d说的是假话 { a = 0; c = 1; d = 1; fd = 0; } if ((a + b + c + d + fd == 1) && (fd == 0))//锁定唯一的凶手 { printf("A是%d,B是%d,c是%d,d是%d\n", a, b, c, d);//这里结果为1的那个人就是凶手 } } return 0; }
结果展示