一、猜凶手:
要求:
找凶手,凶手是四个嫌疑犯之一
a说:不是我
b说:是c
c说:是d
d说:c在说谎
已知四个人中有三个人说的是真话一个假话,请找出真凶!
void FindKiller()
{
char killer = 'A'; //假设凶手是‘A’
for(;killer<='D';killer++){
if ((killer != 'A') + (killer == 'C') + (killer == 'D') + (killer != 'D') == 3) {
//因为四个人只有一个人说谎,故所有条件加起来有三个为真(1)
printf("found you:%c\n", killer);
}
}
}
int main()
{
FindKiller();
system("pause");
return 0;
}
二、猜名次:
要求:
5位运动员参加了10米台跳水比赛,有人让他们预测比赛结果:
A选手说:B第二,我第三;
B选手说:我第二,E第四;
C选手说:我第一,D第二;
D选手说:C最后,我第三;
E选手说:我第四,A第一;
比赛结束后,每位选手都说对了一半,请编程确定比赛的名次。
void Show()
{
int a = 1;
for (; a <= 5; a++) { //枚举法 ,假设 a 是第一名
int b = 1;
for (; b <= 5; b++) {
int c = 1;
for (; c <= 5; c++) {
int d = 1;
for (; d <= 5; d++) {
int e = 1;
for (; e <= 5; e++) {
//对于四位运动员说的话一半正确,所以将一句话分为前后两个条件
//(只有一个条件满足),即 A + B = 1
if (((b == 2) + (a == 3)) == 1 && ((b == 2) + (e == 4)) == 1 && ((c == 1) + (d == 2) == 1 && ((c == 5) + (d == 3) == 1 && ((e == 4) + (a == 1) == 1)))) {
unsigned char flag = 0; //0000 0000
//flag 的 bit位用于记录a b c d e 名次,便于检查名次的连续性
flag |= (1 << (a - 1));
// 1 左移(a-1)后与flag取 或 关系,用于标记名次(下面类似)
flag |= (1 << (b - 1));
flag |= (1 << (c - 1));
flag |= (1 << (d - 1));
flag |= (1 << (e - 1));
//while (flag) {
// if (!(flag & 1)) {
// break;
//判断flag 中1 是否连续(也就是判断名次连续没有中间空名次)
// }
// flag >>= 1;
//}
//if(!flag){
if(flag==0x1F) { // flag 00 01 11 11----0x1F
printf("a=%d, b=%d, c=%d, d=%d, e=%d\n", a, b, c, d, e);
}
}
}
}
}
}
}
}
int main()
{
Show();
system("pause");
return 0;
}
三、说明
1、要明确条件判定真假(0为假,!0 为真);
2、善于运用函数的调用;
3、要注意区分:
| ,& ,&& ,==(恒等于) ,=(赋值)
| :按位或,有一个为1 结果为1 — 0 | 1=1 ,0|0=0 ;
||:逻辑或,链接两个条件,有一个为真则结果为真;
&:按位与,同1为1 ---- 1&1=1,1&0=0 ;
&&:逻辑与 ,连接两个条件,同为真结果为1,否则为0;