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

解决方案 »

  1.   

    whb123() 
    总共有100顶黑的和100顶白的,帽子是随机带的
    他们的帽子怎么可能是同色呢????
    事先不会知道他们的帽子是什么颜色的,而且也不是黑白平均分配的
      

  2.   

    klsxd() ( ) 信誉:100    Blog  2006-12-19 17:18:13  得分: 0  
        
    :-),想出一个办法,
    黑分长音和短音
    白分长音和短音
    令:
     黑:长--自己黑前面一位黑 ;短--自己黑前面一个白
     白:长--自己白前面一位黑 ;短--自己白前面一个白运气不好杀一个
    =================  
     
    最后一人看前面的黑帽是单还是双,单报白,双报黑(以下直接用单双代表黑白);
    接下来的人看后面的报了单/双再看前面的人数是单还是双,相反,报双,反之报单;
    再接下来的人再根据后面报了单/双再看前面的人数是单还是双,相反,报双,反之报单;
    (到这里要说明一下,判断后面的单还是双只要算一下后面所有的人的报的单是不是奇数次就可以了,是-单;不是,双.犯人们应该不会记错吧,小命在此一记呀)
    .....结果:运气不好杀一个~
      

  3.   

    同意ww_goddess()
    得有一半人去赌博,至少会留下50人.这就是考验团队精神的时候啊.
      

  4.   

    楼上的说法是错误的
    比如A,B,C三个人,C说B帽子的颜色,但是B不能说A帽子的颜色,必须按照C说的说出自己帽子的颜色才能生存啊
      

  5.   

    welshem(天堂客)说的应该就是正解
      

  6.   

    经过严格的推算  welshem(天堂客)的算法完全正确  不信大家可以随便举个偶数个人的例子算一下   明白原理滴讲一下啦
      

  7.   

    malligator(不能再整天泡在CSDN里了!) ( ) 信誉:100    Blog    也系正确滴啦
      

  8.   

    最多能活99人,那个第一次回答的人,我们假设其名为A,要有奉献精神,因为他活的机率只有50%。
    方法:A回答时直接说出他前面那位的头顶帽子颜色。
          这时倒数第二个人回答时,就知自己帽子颜色为X和在他前面那位帽子颜色Y(他可以看见)。
          如果X=Y,则这个人立即回答X(这暗示着他前面那位帽子颜色为X)。
          如果X!=Y,则这个人过10秒钟后回答X(这暗示着他前面那位帽子颜色与X相反)。
          其后,所有的人依照这种方法回答。
          结果可以活后面的99人,而第一个回答的人,只有靠上天了,其活的机率为50%。
    记:必竟没有要求犯人回答所用的时间。^_^
      

  9.   

    welshem(天堂客)我感觉他的不正确,不知道是我没有理解他的方法,还是就是如此,我举个例子,比如有6个人,白为0,黑为1,队伍是这样拍的
    001100,第一个人看到前面有两个1,则报白,然后队伍成为这样
    01100,第二个人看到前面有两个1,则应该报白,而且前面报了白,那么相同报白,队伍变为:
    1100,第三个人看到前面1个1,则应该报黑,而且前面报了白,相反报黑,那么队伍变成:
    100,第四个人看到前面没有1,则应该报白,而且前面报了黑,相反报黑,那么队伍变成:
    00,第五个人看到前面没有1,则应该报白,而且前面报了黑,相反报黑,被杀,同理,下一个人也会被杀,这样算上第一个人有可能被杀死,按这种方法就不只是1个人被杀了,被杀的可能性如果只有那两个黑帽,那么后面的人都会被杀死。
      

  10.   

    welshem(天堂客)我感觉他的不正确,不知道是我没有理解他的方法,还是就是如此,我举个例子,比如有6个人,白为0,黑为1,队伍是这样拍的
    001100,第一个人看到前面有两个1,则报白,然后队伍成为这样
    01100,第二个人看到前面有两个1,则应该报白,而且前面报了白,那么相同报白,队伍变为:
    1100,第三个人看到前面1个1,则应该报黑,而且前面报了白,相反报黑,那么队伍变成:
    100,第四个人看到前面没有1,则应该报白,而且前面报了黑,相反报黑,那么队伍变成:
    00,第五个人看到前面没有1,则应该报白,而且前面报了黑,相反报黑,被杀,同理,下一个人也会被杀,这样算上第一个人有可能被杀死,按这种方法就不只是1个人被杀了,被杀的可能性如果只有那两个黑帽,那么后面的人都会被杀死。
      

  11.   

    welshem(天堂客)的思路是正确的。
    首先最后一个人报完之后所有人都知道黑帽子(白帽子也一样)总数是奇数还是偶数。
    前面的99个人都报的是自己帽子的正确颜色,因为自己之前的帽子都能看得到,自己之后的帽子都已经报过颜色,等于其它所有人的帽子颜色都能看到,加上又知道帽子颜色的奇偶性,就能知道自己头上的帽子颜色。
      

  12.   

    5K不算多呀,我们的招聘都不止这个数。赴日软件工程师:1.两年工作经验,至少有一年软件项目经验
    2.日语可基本交流,能流利交流更佳
    3.学历:本科学士学位,计算机相关专业,或大专(正规全日制大专,同时拥有信息产业部的程序员证书)
    国内开发部SE:1.熟悉java、 vb、.net其中一种;
    2.有一定日语基础,能看懂日文式样书;
    3.两年以上软件开发经验。联系方式:[email protected](邮件并MSN)
      

  13.   

    welshem(天堂客),但不是正解ww_goddess() 的是正是正解按着上面两位的办法:
    最后面个肯定只有50%的概率活命,但它可以替前面一个提供信息
    第100个的回答可以让第99个知道自己头是戴的是什么帽子
    这时第99个是继续为第98个提供信息,还是准确的说出自己戴的是什么帽子呢?估计肯定是让自己活命了如果第98和99头上的帽子一样,99,98都能活
    可是不一样,那第98个人就跟第100个人是相同的命运了根据楼上提供的参考:
    前提:事先达成协议,后面一个替前面一个提供信息
    即偶数个为奇数个提供信息
    所以,奇数个都能活命,偶数个50%的概率活命总的活命率 >= 75%
      

  14.   

    俺觉着hyg7276476()的办法好。引用:

    最多能活99人,那个第一次回答的人,我们假设其名为A,要有奉献精神,因为他活的机率只有50%。
    方法:A回答时直接说出他前面那位的头顶帽子颜色。
          这时倒数第二个人回答时,就知自己帽子颜色为X和在他前面那位帽子颜色Y(他可以看见)。
          如果X=Y,则这个人立即回答X(这暗示着他前面那位帽子颜色为X)。
          如果X!=Y,则这个人过10秒钟后回答X(这暗示着他前面那位帽子颜色与X相反)。
          其后,所有的人依照这种方法回答。
          结果可以活后面的99人,而第一个回答的人,只有靠上天了,其活的机率为50%。
    记:必竟没有要求犯人回答所用的时间。^_^
      

  15.   

    俺觉着hyg7276476()的办法好。引用:

    最多能活99人,那个第一次回答的人,我们假设其名为A,要有奉献精神,因为他活的机率只有50%。
    方法:A回答时直接说出他前面那位的头顶帽子颜色。
          这时倒数第二个人回答时,就知自己帽子颜色为X和在他前面那位帽子颜色Y(他可以看见)。
          如果X=Y,则这个人立即回答X(这暗示着他前面那位帽子颜色为X)。
          如果X!=Y,则这个人过10秒钟后回答X(这暗示着他前面那位帽子颜色与X相反)。
          其后,所有的人依照这种方法回答。
          结果可以活后面的99人,而第一个回答的人,只有靠上天了,其活的机率为50%。
    记:必竟没有要求犯人回答所用的时间。^_^
    ------------------------------------------------------------------------
    沒錯
      

  16.   

    ...如果按我说的方法:
    A,最后一个人报其它人黑帽的单双数(此人性命由天定,不管他了~以下说的所有人指的是99人).
    B,所有人是不是能知道除自己外的人的黑帽的单双数单双数呢?后面的都报对了(其中倒数第二人没有这个,他看到的就是除自己外的人的黑帽的单双数单双数了~),前面的都可以看得到
    C,由A又知,总体黑帽的的单双数,从而肯定可以判断出来自己的是黑还是白的.B和C是互为条件的,其中有哪个傻冒非得要报错或者脑袋不灵光整点差错,那就不是我们所能解救的了~有些朋友问"第一个人如果看到前面99个都是白(或者全黑:这两个只有一个是所谓的危险,取决于单双怎么定义的)帽子,他的生存几率是多少??"
    我知道你很想说这种情况他的生存几率是1/101,因为所谓的随机~
    但是,我想问一下,如果随机的话出现这种情况的机率又是多少呢?
    等于0.5的99次,约等于10的30次方分之一!!(如果对30次方没有概念的话,我提醒一下:8次是亿,16次是亿亿,买一次体彩就中头奖的机率约是300亿分之一,...)
      

  17.   

    偶觉得许多人过分强调了最后一个人的求生欲望
    这不符合出题者的本意
    这道题的意思是100个犯人想出一个可行的方法
    所有人都会按这个方法严格执行
    而不是加入个人的情感因素因此奇偶的那个方法是正解
    从信息论的观点考虑这个问题我觉得很有意思
    每个人说黑/白有1bit的信息量,这个信息量如果给的恰当的话可以让所有前面的人多知道一个人的帽子的颜色,如果设计好的方案这个人恰是自己,则可以保证99人活,但最后一个人不可能保证活,因此他只好负责提供信息,因此奇偶的那个是正解
      

  18.   

    WYlslrt(WY.lslrt http://www.wyos.net) :
    1、最后一个人如果看到奇数顶帽子报“黑”否则报“白”,他可能死
    2、其他人记住这个值(实际是黑帽奇偶数),在此之后当再听到黑时,取反一次
    3、从倒数第二人开始,就有两个信息:记住的值与看到的值,相同报“白”,不同报“黑”这是算法
    按你的情况:
    未开始
    位置:6  5  4  3  2  1
    状态:0  0  1  1  0  0
    可见:0  0  1  0  0  0
    信息:无
    第一人说白(0)(赌)
    位置:6  5  4  3  2  1
    状态:0  0  1  1  0  0
    可见:0  0  1  0  0  0
    信息:   0  0  0  0  0
    死活:活
    第二人说白(0)(同)
    位置:6  5  4  3  2  1
    状态:0  0  1  1  0  0
    可见:0  0  1  0  0  0
    信息:      0  0  0  0
    死活:活 活
    第三人说黑(1)(不同)
    位置:6  5  4  3  2  1
    状态:0  0  1  1  0  0
    可见:0  0  1  0  0  0
    信息:         1  1  1(取反)
    死活:活 活 活
    第四人说黑(1)(不同)
    位置:6  5  4  3  2  1
    状态:0  0  1  1  0  0
    可见:0  0  1  0  0  0
    信息:            0  0(取反)
    死活:活 活 活 活
    第五人说白(0)(同)
    位置:6  5  4  3  2  1
    状态:0  0  1  1  0  0
    可见:0  0  1  0  0  0
    信息:               0
    死活:活 活 活 活 活
    第六人说白(0)(同)
    位置:6  5  4  3  2  1
    状态:0  0  1  1  0  0
    可见:0  0  1  0  0  0
    信息:
    死活:活 活 活 活 活 活
      

  19.   

    isy84()的方法最实用,支持!其实10秒太久了,3秒就行!
    天堂客可能是搞硬件驱动编程或数字逻辑的.
      

  20.   

    isy84()的方法 应该不符合出题者的本意。
      

  21.   

    天堂客的是对的,用PHP写了推演,有条件的可以自己试试,代码在:
    http://hi.baidu.com/rainchen/blog/item/cc5f5c608b6129df8cb10d5c.html
      

  22.   

    写了下Java的代码
    /*
     * Rul.java 规则接口
     * 只能做两件事
     *    听到黑后反转信息:reverse(String color)
     *    说出自己的判断:say()/lastSay()
     */
    package ocean.accp.csdn;public interface Rule {
    /**
     * 说出自己的判断
     * @return 黑/白
     */
    public String say();
    /**
     * 最后的人说出自己的判断
     * @return 黑/白
     */
    public String lastSay(); /**
     * 由参数判断是否反转信息
     * @param color 听到的信息
     */
    public void reverse(String color);
    }/*
     * Gaolbird.java 囚犯类
     * 实现规则接口
     * 这样作为队列一员他只能做两件事
     *    听到黑后反转信息:reverse(String color)
     *    说出自己的判断:say()/lastSay()
     */
    package ocean.accp.csdn;public class Gaolbird implements Rule{
    private int capColer=0,capInfo=0,capSee=0; public int getCapColer() {
    return capColer;
    } public void setCapColer(int capColer) {
    this.capColer = capColer;
    }

    public String mycap(){
    return capColer==1?"黑":"白";
    } public int getCapInfo() {
    return capInfo;
    } public void setCapInfo(int capInfo) {
    this.capInfo = capInfo;
    } public int getCapSee() {
    return capSee;
    } public void setCapSee(int capSee) {
    this.capSee = capSee;
    }

    public String say(){
    String rt="白";
    if(capInfo!=capSee){
    rt="黑";
    }
    return rt;
    }
    public String lastSay(){
    return capSee%2==0?"白":"黑";
    }
    public void reverse(String color){
    if(color.equals("黑")){
    capInfo=(capInfo==0?1:0);
    }
    }
    }/*
     * Test.java 测试
     */
    package ocean.accp.csdn;public class Test {
    private Rule[] list=null;
    public Test(int count){
    list=new Rule[count];
    //发帽子,顺带设置一下自己看到的值(第一人为0)
    int mySee=0;
    for(int i=0;i<count;i++){
    list[i]=new Gaolbird();
    //在自己戴帽子之前设置
    ((Gaolbird)list[i]).setCapSee(mySee%2);
    //戴帽子了
    ((Gaolbird)list[i]).setCapColer(Math.random()>0.5?1:0);
    //为后一个人作准备
    mySee+=((Gaolbird)list[i]).getCapColer();
    }
    }
    public static void main(String[] args) {
    Test test=new Test(100);
    test.run();
    test.survivor();
    }
    public void run(){
    String info=null;
    for(int j=list.length-1;j>=0;j--){
    //从后向前说出自己的结果
    if(j==list.length-1){
    info=list[j].lastSay();
    }else{
    info=list[j].say();
    }
    //其他人改
    for(int i=0;i<j;i++){
    list[i].reverse(info);
    }
    }
    }
    public void survivor(){
    String capColor=null,capSay=null,rt=null;
    for(int i=0;i<list.length;i++){
    capColor=((Gaolbird)list[i]).mycap();
    if(i==list.length-1){
    capSay=list[i].lastSay();
    }else{
    capSay=list[i].say();
    }
    rt=capColor.equals(capSay)?"生":"死";
    System.out.printf("第%3d个犯人\t带%s帽\t说'%s'\t%s\n",i+1,capColor,capSay,rt);
    }
    }
    }
      

  23.   

    welshem(天堂客)写的代码好棒,实现了这个功能,完全正确无误!
    呵呵
      

  24.   

    welshem(天堂客)的理论:
    1、最后一个人如果看到奇数顶帽子报“黑”否则报“白”,他可能死
    2、其他人记住这个值(实际是黑帽奇偶数),在此之后当再听到黑时,取反一次
    3、从倒数第二人开始,就有两个信息:记住的值与看到的值,相同报“白”,不同报“黑”但是如果所有人都代"白",最后一个人如果看到奇数顶帽子报“黑”.
    从倒数第二人开始,就有两个信息:记住的值与看到的值,相同报“白”,不同报“黑”.
    那岂不是99人必死???
      

  25.   

    我来说说我的思路吧:
    1、最后一个人我想只能是赌命的,但他的信息能不能给其他人帮助?如果行,那就是只会死一个。
    2、黑白让我想起1、0,想对于最后一个,倒数第二个少看到的就是自己的那顶要命的帽子,也就是少了个1/0
    3、由于不能报自己看到了多少个1、0所以只能把这此数并起来
    4、0 就不管了,就计1,报奇偶(实际上就是所见0、1之和的最低位啦)那好,方法有了
    1、最后一个人如果看到奇数顶【黑】帽子报“黑”否则报“白”,他可能死
    2、其他人记住这个值(实际是黑帽奇偶数),在此之后当再听到黑时,取反一次
    3、从倒数第二人开始,就有两个信息:记住的值与看到的值,相同报“白”,不同报“黑”99人能100%活,1人50%能活有上下文的ww_goddess() 没看上文,我也少打了个【黑】,抱歉,抱歉
      

  26.   

    welshem(天堂客) 大哥,我还是没理解,不好意思.
    如果前面99人带"黑",最后一个人看到奇数顶【黑】帽子报“黑”
    从倒数第二人开始,就有两个信息:记住的值与看到的值,相同报“白”,不同报“黑”
    看到的是"黑",记住的是"黑",则相同报“白”,但他带的是"黑"啊?