【06】分配任务

某任务需要在A、B、C、D、E这五人中物色人员去完成,但派人受限于下列条件:

  1. 若A去,则B跟去
  2. D,E两人中必有人去
  3. B,C两人中必有人去,但只去一人
  4. C,D两人要么都去,要么都不去
  5. 若E去,则A、B都去
问这五个条件如何表示?

令A、B、C、D、E都为逻辑型值true或false。则:

条件1可以表示为逻辑表达式:A—>B,它等价于!A || B,意即A不去是一种方案, 另一种方案当然是A和B一起去。

条件2可以表示为:D || E,意即D去,E去,D和E都去,这三种方案都行.

条件3可以表示为:(B&&!C) || (!B&&C)。推演为B != C.意即,B去C不去是一种 方案,另一种方案是C去B不去。

条件4可以表示为:( !C || D ) && ( C || !D).更简单的形式为C == D·意即C和D一起去 是一种方案,C和D都不去是另一种方案

条件5可以表示为:!E || (A&&B),意即E不去是一种方案,另一种方案是E和A和 B都去

求解模式

如果将每个人的去与不去看成是5位整数的其中1位,其中A对应最高位,E对应最低位,那么,所有可能的调派方案为从全部不派的00000到全部派去的11111之间变化。显然有32种方案。全部遍历的循环为:
1
for( int i=0; i<32; i++ )

其中每个i对应一个二进制数,为一种调派方案。在某一种调派方案i中:

A为最高位 (i & 16 ) >> 4或者 i>>4  (将低位都挤掉)
B为次高位 ( i & 8 ) >> 3
C为中间位 ( i &4 ) >> 2
D为次低位( i & 2 )>>1
E为最低位 i&1

根据求解模式,把这五个条件表示成否定的形式:

否定条件1为 !( !A || B ) = A && !B
否定条件2为!(D || E )
否定条件3为 B=C
否定条件4为C != D
否定条件5为E && !( A && B)

再将A、B、C、D、E的式子带入条件表达式,既可以构成程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include<iostream>
using namespace std;
void print(int n);
void main() {
for( int i=0; i < 32; i++ ) {
bool A=i&16, B=i&8, C=i&4, D=i&2, E=i&1;
if( A && !B )
continue;
if( !D && !E )
continue;
if( B==C )
continue;
if( C != D )
continue;
if( E && !(A && B) )
continue;
print(i);
}
}
void print(int n) {
cout<<( n&16 ? &quot; A &quot;:&quot;~A &quot; )
<<( n&8 ? &quot; B &quot;:&quot;~B &quot; )
<<( n&4 ? &quot; C &quot;:&quot;~C &quot; )
<<( n&2 ? &quot; D &quot;:&quot;~D &quot; )
<<( n&1 ? &quot; E &quot;:&quot;~E &quot; )<<endl;
}

欢迎关注我的其它发布渠道