问题描述:
日本某地发生了一件谋杀案,警察通过排查确定杀人凶手必为4个
嫌疑犯的一个。以下为4个嫌疑犯的供词。
A说:不是我。
B说:是C。
C说:是D。
D说:C在胡说
已知3个人说了真话,1个人说的是假话。
现在请根据这些信息,写一个程序来确定到底谁是凶手。
问题分析:
方法一:
1、每次假设一个人说了谎,4 次循环;
2、1 表示凶手,0 表示清白者;
3、C、D 说话矛盾 ,FD 表示矛盾;
4、当矛盾不存在(fd = 0),且 a+b+c+d = 1,则找到凶手;
5、输出结果,谁为 1 ,谁就是凶手。
四个人三个人说真话,一个人说假话,所以分别假设每个人说假话的情况,并且C,D说话是相互矛盾的,所以要区分开,FD代表对立面:
嫌疑犯 | 是否说谎 | 结论 |
A | 是 | A = 1 C = 1 D = 0 FD = 1 |
B | 是 | A = 0 C = 0 D = 0 FD = 1 |
C | 是 | A = 0 C = 1 D = 0 FD = 0 |
D | 是 | A = 0 C = 1 D = 1 FD = 0 |
方法二:
1、'A' 到 'D' 之间 ASCII 码连续,循环遍历;
2、把他们说的话全转换为表达式如下:
(killer != 'A') + (killer == 'C') + (killer == 'D') + (killer != 'D') == 3;(一共三个人说了真话)
3、如果谁满足这个表达式则谁就是凶手;
源代码:
方法一:
#include<stdio.h>
#include<windows.h>
void main()
{
int i = 0, a = 0, b = 0, c = 0, d = 0;
int fd = 0;
for (i = 1; i <= 4; i++)//在这里有4中可能,所以用for循环循环四次
{
if (i == 1)//假设A说了谎
{
a = 1; c = 1;fd = 1; d = 0;
}
if (i == 2)//假设B说了谎
{
a = 0; c = 0; fd = 1; d = 0;
}
if (i == 3)//假设C说了慌
{
a = 0; c = 1; fd = 0; d = 0;
}
if (i == 4)//假设D说了慌
{
a = 0; c = 1; fd = 1; d = 0;
}
if ((a + b + c + d + fd == 1) && (fd == d))
{
printf("A=%d B=%d C=%d D=%d", a, b, c, d);
}
}
system("pause");
return 0;
}
方法二:
#include<stdio.h>
#include<windows.h>
int main()
{
int killer = 0;
for (killer = 'A'; killer < 'D'; killer++)
//利用ASCII码连续遍历四人
{
if ((killer != 'A') + (killer == 'C') + (killer == 'D') + (killer != 'D') == 3)
//判断条件,三个人只有一人说假话
{
printf("killer is %c\n", killer);
}
}
system("pause");
return 0;
}