百度空间 | 百度首页 
 
查看文章
 
CSDN的一道犯人与帽子推理题的PHP模拟演算
2006-12-20 12:53

http://community.csdn.net/Expert/topic/5241/5241662.xml?temp=.5457727

 

问题如下:有100个犯人,头天晚上被通知第二天一早要带着一顶帽子(总共有100顶黑的和100顶白的,帽子是随机带的,而且不知道自己头上的帽子是什么颜色),排成一列直线队伍,后面的人能看到前面的所有人带的帽子的颜色,前面的看不到后面的人的帽子颜色,现在警官让犯人们先讨论下,等明天排队时,警官从最后一个人问起直到第一个,“你头上带的帽子颜色是黑还是白?”犯人只许说一个字“黑或白”,(说话时没有任何提示,都是标准的一个音,而且没有眼神什么提示,有的只是头天晚上想出的方法)犯人说错直接杀,说对了马上放了,问讨论出一个怎样的方法使被杀的人数确定最少?

第一个报正确答案是:

welshem(天堂客) 

楼上大哥又发了一帖啊,我来说说我的思路吧:
1、最后一个人我想只能是赌命的,但他的信息能不能给其他人帮助?如果行,那就是只会死一个。
2、黑白让我想起1、0,想对于最后一个,倒数第二个少看到的就是自己的那顶要命的帽子,也就是少了个1/0
3、由于不能报自己看到了多少个1、0所以只能把这此数并起来
4、0 就不管了,就计1,报奇偶(实际上就是所见0、1之和的最低位啦)

那好,方法有了
1、最后一个人如果看到奇数顶帽子报“黑”否则报“白”,他可能死
2、其他人记住这个值(实际是黑帽奇偶数),在此之后当再听到黑时,取反一次
3、从倒数第二人开始,就有两个信息:记住的值与看到的值,相同报“白”,不同报“黑”

99人能100%活,1人50%能活

现在最重要的是选最后一个人了,他是50%死的可能的,必须有奉献精神的啊!

 

 

根据其说法用PHP实现的简单模拟演算代码为:

<?php

$count = 100;
$man = array();
$black = array_fill(0, $count, 1);
$white = array_fill(0, $count, 0);

$manInBlack = 0;
$manInWhite = 0;

for($i=1;$i<=$count;$i++)
{
 if(rand(0,1))
 {
  $man[$i] = array_pop($black);
  $manInBlack++;
 }
 else 
 {
  $man[$i] = array_pop($white);
  $manInWhite++;
 }
}

function getFrontBlackCount($queue, $me)
{
 $count = 0;
 for($i=$me-1; $i>=1; $i--)
 {
  if($queue[$i])
  {
   $count++;
  }
 }
 return $count;
}

echo "manInBlack:$manInBlack, manInWhite:$manInWhite \n";
// start
$flag = 0;
for($i=$count;$i>=1;$i--)
{
 $FrontBlackCount = getFrontBlackCount($man, $i);
 $guess = ($FrontBlackCount%2) ^ $flag;
 if($guess)
 {
  $flag = (int)!$flag;
 }
 if($guess ==  $man[$i])
 {
  $result = 'alive';
 }
 else 
 {
  $result = 'die';
 }
 echo "man $i ,his hat is {$man[$i]} , FrontBlackCount=$FrontBlackCount ,newflag=$flag, he guess: $guess, so he will $result \n";
}



类别:Php | 添加到搜藏 | 浏览() | 评论 (0)
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     
 
精彩相册
   
     

©2009 Baidu