谁是偷盗者?

fuyun 2011-03-01
    甲、乙、丙、丁4个嫌疑人,只有1人为偷盗者。在审讯中,四人诚实或说谎都有可能。
    甲:乙没偷,丁偷的;
    乙:我没偷,丙偷的;
    丙:甲没偷,乙偷的;
    丁:我没偷。
    请推断实际的偷盗者。

[解答]
    即使没偷的人也可能说谎,但诚实与说谎是对陈述的整体来说的,每个人要么都说真话,要么都说假话。
    要解决本题,先要将命题符号化,然后数字化来分析,才能编程运行得出结果。
    先将四人说的话符号化,设甲偷为A、乙偷为B、丙偷为C、丁偷为D。
    四人要么说真话,要么说假话,所以甲、乙、丙、丁说的话可以表示为:
    甲:乙没偷并且丁偷的,或者乙偷的并且丁没偷;(~B∧D∨B∧~D)
    乙:乙没偷并且丙偷的,或者乙偷的并且丙没偷;(~B∧C∨B∧~C)
    丙:甲没偷并且乙偷的,或者甲偷的并且乙没偷;(~A∧B∨A∧~B)
    丁:丁没偷或者丁偷的。(D∨~D)(永真陈述)
    已知其中只有一人偷的,所以所有可能的情况只有四种(并不排除说假话者没有偷的可能性):
    A∧(~B∧~C∧~D)    //A偷,其他人没偷
    B∧(~A∧~C∧~D)    //B偷,其他人没偷
    C∧(~A∧~B∧~D)    //C偷,其他人没偷
    D∧(~A∧~B∧~C)    //D偷,其他人没偷
    将符号A、B、C、D对应一个字节中的位,从而数字化(此思路对于求比较简练的解答十分重要)。
    设A=8(即1<<3),B=4(即1<<2),C=2(即1<<1),D=1(即1<<0)
    则所有可能的情况为8,4,2,1。循环可从20~23。
    表达式~B∧D=1,表达式B∧~D=4,所以,A的陈述可描述为数值5,即(00000101)2。对于任何可能性(A、B、C、D偷与没偷的排列组合)表示的数值,只要在第0位和第2位上为1,即符合A陈述的条件。
    表达式~B∧C=2,表达式B∧~C=4,所以,B的陈述可描述为数值6,即(00000110)2。
    表达式~B∧A=8,表达式B∧~A=4,所以,C的陈述可描述为数值12,即(00001100)2。
    表达式D=1,~D=0,D的描述为永真,对推断没有帮助,所以略去。
    如果甲的描述5与甲申偷盗者的假设8满足甲的一种陈述,即1或者4,则说明甲是偷盗者的假设可能成立。
    只要对所有可能的情况(8,4,2,1)循环判断条件是否满足。并且必须满足所有A、B、C、D的陈述命题,才能作为最后的推断依据。

    很多推断的问题,最后都能化到简单的循环(包括所有的可能)中,逐个判断条件满足与否。
fuyun 2011-03-01
附上一种解答:
public class infer{
  public int doInfer(){
    for(int i = 0; i < 4; i++){
      if(!(1 == (1 << i & 5) || 4 == (1 << i & 5)))
        continue;
      if(!(2 == (1 << i & 6) || 4 == (1 << i & 6)))
        continue;
      if(!(8 == (1 << i & 12) || 4 == (1 << i & 12)))
        continue;
      return i;
    }
    return -1;
  }

  public static void main(String[] args){
    infer inf = new infer();
    int result = inf.doInfer();
    switch(result){
      case 0:System.out.println("丁是偷盗者!");break;
      case 1:System.out.println("丙是偷盗者!");break;
      case 2:System.out.println("乙是偷盗者!");break;
      case 3:System.out.println("甲是偷盗者!");break;
      default:System.out.println("无法判断!");
    }
  }
}
qiyang199132 2012-05-04
zdb_cn 2012-05-15
四人要么说真话,要么说假话,所以甲、乙、丙、丁说的话可以表示为:
    甲:乙没偷并且丁偷的,或者乙偷的并且丁没偷;(~B∧D∨B∧~D)
    乙:乙没偷并且丙偷的,或者乙偷的并且丙没偷;(~B∧C∨B∧~C)
    丙:甲没偷并且乙偷的,或者甲偷的并且乙没偷;(~A∧B∨A∧~B)
    丁:丁没偷或者丁偷的。(D∨~D)(永真陈述)

这个感觉有问题,比方说
  甲: 真话,乙没偷,丁偷的,
       假话:1、(乙没偷,丁没偷),
             2、(乙偷了,丁没偷),
             3、(乙偷了,丁偷了)
  应该是假话存在三种可能的
Global site tag (gtag.js) - Google Analytics