A、B、C、D、E、F、G、H、I、J 共10名学生有可能参加本次计算机竞赛,也可能不参加。因为某种原因,他们是否参赛受到下列条件的约束:
1. 如果A参加,B也参加;
2. 如果C不参加,D也不参加;
3. A和C中只能有一个人参加;
4. B和D中有且仅有一个人参加;
5. D、E、F、G少、H 中至有2人参加;
6. C和G或者都参加,或者都不参加;
7. C、E、G、I中至多只能2人参加
8. 如果E参加,那么F和G也都参加。
9. 如果F参加,G、H就不能参加
10. 如果I、J都不参加,H必须参加
请编程根据这些条件判断这10名同学中参赛者名单。如果有多种可能,则输出所有的可能情况。每种情况占一行。参赛同学按字母升序排列,用空格分隔。
比如:
C D G J
就是一种可能的情况。
1. 如果A参加,B也参加;
2. 如果C不参加,D也不参加;
3. A和C中只能有一个人参加;
4. B和D中有且仅有一个人参加;
5. D、E、F、G少、H 中至有2人参加;
6. C和G或者都参加,或者都不参加;
7. C、E、G、I中至多只能2人参加
8. 如果E参加,那么F和G也都参加。
9. 如果F参加,G、H就不能参加
10. 如果I、J都不参加,H必须参加
请编程根据这些条件判断这10名同学中参赛者名单。如果有多种可能,则输出所有的可能情况。每种情况占一行。参赛同学按字母升序排列,用空格分隔。
比如:
C D G J
就是一种可能的情况。
2.!c&&!b
3.a+c<=1
4.(b&&!d)||(!b&&d)
5.(d+e+f+g+h)>=2
6.!(c^g)
7.c+e+g+i<=2
8.e&&g&&f
9.f&&!g&&!h
10.!(i||g)&&h
先挑出1L的一点小毛病先。首先介绍一种逻辑联结词:蕴涵联结词,一般表示形如“如果……就……”的联结词,表示递推的逻辑关系。(数理逻辑的课本上有,不同的版本可能有不同的名称,在下这里只简要介绍下)
符号表示:A->B(如果A就B)
真值表:A B A->B
0 0 1
0 1 1
1 0 0
1 1 1可推出其或非最简式为:
~A+B
符号说明:~A 非A
AB A与B
A+B A或B以A表示“A参加比赛”、B表示“B参加比赛”……
可推出上面给出全部条件的逻辑表达式:
1. A->B (~A+B)
2. ~C->~D (C+~D)
3. ~AC+A~C+~A~C => ~(AC)
4. ~BD+B~D (异或B^D)
5. D、E、F、G、H中至少有2个为真
6. CG+~C~G (同或,即异或取反:~(C^G))
7. C、E、G、I中最多2个为真
8. E->FG (~E+FG)
9. F->~G~H (~F+~G~H => ~F+~(G+H))
10. ~I~J->H (~(~I~J)+H => I+J+H)
综合上面的条件用穷举法就很容易写出代码: public static void main(String[] args) {
boolean[] Bool = { false, true }; for (boolean A : Bool)
for (boolean B : Bool)
for (boolean C : Bool)
for (boolean D : Bool)
for (boolean E : Bool)
for (boolean F : Bool)
for (boolean G : Bool)
for (boolean H : Bool)
for (boolean I : Bool)
for (boolean J : Bool) {
if ((!A || B) //条件1
&& (C || !D) //条件2
&& !(A && C) //条件3
&& (B ^ D) //条件4
&& ((D ? 1 : 0)
+ (E ? 1 : 0)
+ (F ? 1 : 0)
+ (G ? 1 : 0)
+ (H ? 1 : 0) >= 2) //条件5
&& !(C ^ G) //条件6
&& ((C ? 1 : 0)
+ (E ? 1 : 0)
+ (G ? 1 : 0)
+ (I ? 1 : 0) <= 2) //条件7
&& (!E || (F && G)) //条件8
&& (!F || !(G || H)) //条件9
&& (I || J || H)) { //条件10
if (A)
System.out.print("A ");
if (B)
System.out.print("B ");
if (C)
System.out.print("C ");
if (D)
System.out.print("D ");
if (E)
System.out.print("E ");
if (F)
System.out.print("F ");
if (G)
System.out.print("G ");
if (H)
System.out.print("H ");
if (I)
System.out.print("I ");
if (J)
System.out.print("J ");
System.out.println();
}
}
}输出结果:
C D G J
C D G H
C D G H J
B C G H
B C G H J
将i 转换成十位二进制数假设0代表不去 1 代表去在对每种条件进行判断既可以了。
if ((!A || B) //条件1
&& (C || !D) //条件2
&& !(A && C) //条件3
&& (B ^ D) //条件4
&& ((D ? 1 : 0)
+ (E ? 1 : 0)
+ (F ? 1 : 0)
+ (G ? 1 : 0)
+ (H ? 1 : 0) >= 2) //条件5
&& !(C ^ G) //条件6
&& ((C ? 1 : 0)
+ (E ? 1 : 0)
+ (G ? 1 : 0)
+ (I ? 1 : 0) <= 2) //条件7
&& (!E || (F && G)) //条件8
&& (!F || !(G || H)) //条件9
&& (I || J || H)) {