逻辑表达式——谁在撒谎
一、问题描述
三个嫌疑犯在法官面前各执一词,
甲说:“乙在撒谎。”
乙说:“丙在撒谎。”
丙说:“甲乙两个人都在撒谎。”
法官为难,甲乙丙三人到底谁在说谎,谁在说真话?
二、算法思想
三个人中每个人有两种可能,要么说真话,要么说假话,因此通过穷举法即可判断出最终的结果。
假设甲乙丙三个人所说的话用变量a、b、c表示,0代表说假话,1代表说真话。根据题意,列出如下的逻辑表达式:
甲:(a&&!b) || (!a&&b)
乙:(b&&!c) || (!b&&c)
丙:(c&&a+b==0) || (!c&&a+b!=0)
具体的操作利用循环语句解决,设置多重循环依次穷举出三人说真话和假话的所有可能。再利用条件语句进行判断,其条件表达式为:
( (a&&!b) || (!a&&b) ) && ( (b&&!c) || (!b&&c) ) && ( (c&&a+b==0) || (!c&&a+b!=0) )
三、程序代码
#include <stdio.h> int main(){ int a, b, c; for(a=0; a<=1; a++){ for(b=0; b<=1; b++){ for(c=0; c<=1; c++){ if( ((a&&!b) || (!a&&b)) && ((b&&!c) || (!b&&c)) && ((c&&a+b==0) || (!c&&a+b!=0)) ){ printf("甲说的是%s。\n", a?"真话":"假话"); printf("乙说的是%s。\n", b?"真话":"假话"); printf("丙说的是%s。\n", c?"真话":"假话"); } } } } return 0; }
补充:条件运算符的优先级低于关系运算符和算术运算符,但高于赋值运算符。因此max=(a>b)?a:b,可以去掉括号写为max=a>b?a:b。条件运算符的结合方向是从右至左。
四、运行结果