您的位置:首页 > 其它

(MS100—22)有4张红色的牌和4张蓝色的牌的一道推理题

2013-09-11 22:12 239 查看
有4张红色的牌和4张蓝色的牌的一道推理题

题目:

有4张红色的牌和4张蓝色的牌,主持人先拿任意两张,

再分别在A、B、C三人额头上贴任意两张牌,

A、B、C三人都可以看见其余两人额头上的牌,

看完后让他们猜自己额头上是什么颜色的牌,

A说不知道,B说不知道,C说不知道,然后A说知道了。

请教如何推理,A是怎么知道的。如果用程序,又怎么实现呢?

解答:
因为第一次三者都说不知道,则两两相加不可能出现四红或四蓝,则A,B,C中必须至少有一个是红蓝。
A看B和C,如果B和C中是两红和两蓝,则A第二次可以确定自己是红蓝。同理B和C也是,则这种方式成立。

除此之外,剩下二种组合方式:三个人都是红蓝;两个人红蓝,一个人是两红或两蓝。
三个人都是红蓝,三个人都是红蓝,A就不说了,可以判断。
如果A,B,C中有一个是两红和两蓝,那么另两个就可以第二次判断出自已是红蓝。而此人只能判断出自己是两红或者是两蓝,那么A不能判断自己,所以A是红蓝,B和C是中有一个是红蓝,一个是两红或两蓝.
所以A是红蓝,B和C不确定。

一个效率低的穷举法解法为:
// 假定0为红,1为蓝色
//

bool isknown(int* m, int* n)
{
int red = 0;
int blue = 0;

for (int i=0; i<2; ++i)
{
if ( m[i] == 0 )
{
red++;
}
else
{
blue++;
}

if ( n[i] == 0 )
{
red++;
}
else
{
blue++;
}
}

if ( red > 2 || blue > 2 ) //因为至少有一个红蓝,那么在判断的时候红色大于2或者蓝色大于2.
{
return true;
}

return false;
}

bool get(int* a, int* b, int* c, int* d)
{
// 遍历所有的可能性
bool found = false;
for (int a1=0; a1<2; ++a1)
{
a[0] = a1;
for (int a2=0; a2<2; ++a2)
{
a[1] = a2;

for (int b1=0; b1<2; ++b1)
{
b[0] = b1;
for (int b2=0; b2<2; ++b2)
{
b[1] = b2;

for (int c1=0; c1<2; ++c1)
{
c[0] = c1;
for (int c2=0; c2<2; ++c2)
{
c[1] = c2;

if ( !isknown(a,b) && !isknown(a,c) && !isknown(b,c) )
{
return true;
}

}
}
}
}
}
}

return true;
}

int main(int argc, char* argv[])
{
int a[2], b[2], c[2], d[2];
get(a,b,c,d);

printf("a:%d,%d, b:%d,%d, c:%d,%d", a[0], a[1], b[0], b[1], c[0], c[1]);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐