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

解决方案 »

  1.   

    我是楼主:贴上答案和代码
    推理过程:100个人第一天商量好:
    1.在黑白中选一个幸运色   比如为黒
    2.那么第二天站在第100位的人,看到前面的黑帽数为奇数就报黑,反之报白。(这个地方黑白不要颠倒。我感觉这样机率要比五成稍微大一点。毕竟不是搞数学的,这个地方明于 心而不明于口)这样前面一个人就知道,从第一个人到自己黑白帽数量是为奇还是为偶。而自己前面黑白帽数量是为奇还是为偶是可以看到的,因此可以判断自己帽子的颜色。
    3.如果这一百个人都操作无误。第一个人活的概率略大于0.5
    后面的人可以保证活下来。。写了下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.println("第"+(i+1)+"个犯人"+"带"+capColor+"帽"+"说"+capSay+rt);
    }
    }
    }