谁是窃贼

/*公安人员审问四名窃贼嫌疑犯。已知,这四人当中仅有一名是窃贼,还知道这四人中每人要么是诚实的,要么总是说谎的。在回答公安人员的问题中:
甲说:“乙没有偷,是丁偷的。”
乙说:“我没有偷,是丙偷的。”
丙说:“甲没有偷,是乙偷的。”
丁说:“我没有偷。”
请根据这四人的答话判断谁是盗窃者。
*问题分析与算法设计
假设A、B、C、D分别代表四个人,变量的值为1代表该人是窃贼。
由题目已知:四人中仅有一名是窃贼,且这四个人中的每个人要么说真话,要么说假话,而由于甲、乙、丙三人都说了两句话:“X没偷,X偷了”,故不论该人是否说谎,他提到的两人中必有一人是小偷。故在列条件表达式时,可以不关心谁说谎,谁说实话。这样,可以列出下列条件表达式:
甲说:”乙没有偷,是丁偷的。” B+D=1
乙说:“我没有偷,是丙偷有。” B+C=1
丙说:“甲没有偷,是乙偷的。” A+B=1
丁说:“我没有偷。” A+B+C+D=1
其中丁只说了一句话,无法判定其真假,表达式反映了四人中仅有一名是窃贼的条件。
*程序说明与注释
#include <stdio.h>
void main()
{int i,j,a[4];
for(i=0;i<4;i++) //假定只有第i个人为窃贼
{for(j=0;j<4;j++) //在第i轮假设中,假设第i个人为窃贼,把a[i]设为1,其余为0
{if(j==i)a[j]=1;
else a[j]=0;}
if(a[3]+a[1]==1&&a[1]+a[2]==1&&a[0]+a[1]==1) //判断条件是否成立
{printf("The thief is "); //成立
for(j=0;j<=3;j++) //输出计算结果
{if(a[j])printf("%c.",j+'A');
}
printf("\n");}}}


*/

笔者自己思考了一个通常的方法:

#include"stdio.h"
#include"stdlib.h"
#include"time.h"
int main()
{int a[4];//代表甲乙丙丁的结果
for(int k1=0;k1<2;k1++)
{if(k1)
{ a[1]=0; a[3]=1;}//真话原样
else { a[1]=1; a[3]=0; }
for(int k2=0;k2<2;k2++)
{if(k2&&k1)
 {a[1]=0; a[2]=1;}//甲乙两个人讲的话没有矛盾,同真,或者同假
else if(!k1&&!k2) {a[1]=1; a[2]=0;}
else continue;
for(int k3=0;k3<2;k3++)
{if(k3&&(!k1||!k2))//甲乙之中如果有一个人说了谎话,那么与丙说的话没有矛盾
{a[0]=0; a[1]=1;}
else if(!k3&&k1&&k2){a[0]=1; a[1]=0; }
else continue;
for(int k4=0;k4<2;k4++)
{if(k4&&!k1)
	a[3]=0;
else a[3]=1;
if(a[0]+a[1]+a[2]+a[3]==1)
for(int i=0;i<4;i++)
if(a[i]){printf("%d\n",i+1); break; }
}//end k4
}//end k3;
}//end k2;
}//end k1;
printf("\n");
system("pause");
}



你可能感兴趣的:(c,逻辑推理)