6-谁是嫌疑犯——用二进制枚举
只有6个嫌疑人,用了6层循环,如果有更多嫌疑人呢?
不写多重循环怎么办呢?我们应该是有办法的
每个嫌疑人指定一个二进制的位
把所有人是不是参与作案的情况拼在一起,拼成
六位二进制数



怎么根据循环变量的值得到每一位嫌疑人是否作案的信息
怎么让程序得到一个数二进位的每一位值?
位运算
在数的二进制表示意义下所做的操作

按位与
&1保持原来的值,&0都会变成0,
通过&一个特定的值,可以设置某些位为1,
其他位不变
按位或
|1都会变成1,|0保持原来的值
通过|一个特定的值,可以设置某些位为1,
其他位不变
按位异或
^1会变,^0保持原来的值,
通过^一个特定的值,可以将某些位变化,其他位不变
按位取反
所有位都变化
往右移位


往左移位

for(int i = 0; i < (1<<6); i++)
左移n位,相当于乘以2的n次方
2的6次方即1<<6
通过位运算操作二进制中特定位,取特定位上的一个值,或让特定位变成0、1或反转
D是否作案?



/*
A、B至少有一人作案
A、E、F三人中至少有两人参与作案
A、D不可能是同案犯
* B、C或同时作案,或与本案无关
C、D中有且仅有一人作案
如果D没有参与作案,则D也不可能参与作案
(A == 1) || (B == 1)
(A == 1 && E == 1) || (A == 1 && F == 1) || (E == 1 && F == 1)
!((A == 1) && (D == 1))
(B == 1) && (C == 1) || (B == 0) && (C == 0)
(C == 1) && (D == 0) || (C == 0) && (D == 1)
(D == 0) && (E == 0) || (D == 1)
*/
#include <iostream>
using namespace std;
int main() {
for (int i = 0; i < (1 << 6); i++) {
int A = (i >> 5) & 1;
int B = (i >> 4) & 1;
int C = (i >> 3) & 1;
int D = (i >> 2) & 1;
int E = (i >> 1) & 1;
int F = i & 1;
bool b1 = (A == 1) || (B == 1);
bool b2 = (A == 1 && E == 1) || (A == 1 && F == 1) || (E == 1 && F == 1);
bool b3 = !((A == 1) && (D == 1));
bool b4 = (B == 1) && (C == 1) || (B == 0) && (C == 0);
bool b5 = (C == 1) && (D == 0) || (C == 0) && (D == 1);
bool b6 = (D == 0) && (E == 0) || (D == 1);
if (b1 && b2 && b3 && b4 && b5 && b6) {
cout << A << B << C << D << E << F << endl;
break;
}
}
return 0;
}
运算结构

人赋予了计算机逻辑分析与推理的能力
计算机确实有强大的逻辑分析功能。实际上是人通过程序赋予它的。一些逻辑问题必须转换成计算机能够看懂的表达式,并且通过一系列一定程序指令才能让计算机通过计算找出答案。本来作案不作案计算机无法计算,但通过一些方法把自然语言的描述,转化成可计算的表达式,把看起来不能算的问题,变得可算,把可算的表达式用程序语言组织起来。顺序、分支、循环语句有序组织使得解决问题成为可能。

浙公网安备 33010602011771号