蓝眼人

我看到一道题,大致说是岛上有100个囚犯,全是蓝眼睛,后来有个医生一语道破天机,囚犯知道自己眼睛的颜色,找到守卫获得自由。
这个问题的关键点在于递归推理,我把这个问题变了一下,然后写了一个程序,核心代码是reasoning方法。
如果你有更好的写法,欢迎分享~

package zms;

import java.util.ArrayList;
import java.util.List;

/**
 * 岛上有 M 个囚犯,
 * 但是他们都只能看到别人眼睛的颜色,并不能知道自己的眼睛颜色,
 * 而且他们之间不能去谈论眼睛颜色的话题,规定每天晚上都可以有一个人去找守卫说出自己的眼睛颜色,如果错了被杀死,如果对了被释放。
 * 但是大家在没有十足的把握前都不敢去找守卫,
 * 有一天,一个医生对他们说:"你们之中至少有一个蓝眼睛,其他的都是红眼睛”
 * 然后 N 天,这些人都获救了,为什么?这句话对他们有什么影响?
 */
public class BlueEye {
    
    

    //囚犯Prisoner类
    static class Prisoner{
    
    
        int id; //编号
        String eyeColor;   //眼睛颜色
        int day;    //医生点破秘密的第几天
        boolean isFree = false; //是否被释放
        public Prisoner(int id, String eyeColor){
    
    
            this.id = id;
            this.eyeColor = eyeColor;
        }
        /**
         * 蓝眼囚犯开始推理
         * @param array 线索 {knowLestBN,blueNum,day}
         * @return array  递归函数,经过推理,更新knowLestBN
         */
        private int[] reasoning(int[] array){
    
    
            int knowLestBN = array[0];  //知道 所有人都知道 至少有knowLestBN个蓝眼睛
            int blueNum = array[1]; //岛上蓝眼人数量
            //不知道至少有几个蓝眼人 ==> 陷入死循环
            if(knowLestBN == 0) {
    
    
                array[0] = knowLestBN;
                return reasoning(array);
            }
            //过一天后,了解到所有人都不知道蓝眼人数量 ==> 推断所有人知道至少有knowLestBN+1个蓝眼人
            if(knowLestBN != blueNum) {
    
    
                array[0]++;
                array[2]++;
                return reasoning(array);
            }
            //剩下的情况就是蓝眼人知道自己是蓝眼人了,然后就求释放
            if(this.eyeColor == "蓝眼") {
    
    
                release(array[2]);
                return array;
            }            
            //次日,红眼人看见蓝眼人不见了,就知道自己是红眼人了
            array[2]++;
            release(array[2]);
            return array;
        }

        /**
         * 蓝眼囚犯求释放
         */
        private void release(int day) {
    
    
//            System.out.println("第" + day + "天," + this.eyeColor + "的" + this.id + "号囚犯找到守卫求释放" );
        }

    }

    //运行程序,描述整个故事的过程
    public static void main(String[] args) {
    
    
        //总共有100个囚犯
        int num = 100;
        //岛上蓝眼人数量
        int blueNum = 100;
        //把囚犯关押在一座小岛上
        List<Prisoner> island = new ArrayList<>();
        for(int i=0; i<blueNum; i++) {
    
    
            island.add(new Prisoner(i+1,"蓝眼"));
        }
        for(int i=blueNum; i<num; i++) {
    
    
            island.add(new Prisoner(i+1, "红眼"));
        }
        //医生告诉囚犯们至少有一个蓝眼人
        int knowLestBN = 1;
        //共识线索{已知至少有多少蓝眼人,实际蓝眼人数,获得线索的第几天}
        int[] array = {
    
    knowLestBN,blueNum,1};
        // 岛上的蓝眼囚犯开始推断
        for(int i=0; i<island.size(); i++) {
    
    
            island.get(i).reasoning(array);
            if(i != island.size()-1) {
    
    
                array = new int[] {
    
    knowLestBN,blueNum,1};
            }
        }

        System.out.println(array[2] + "天后,所有的囚犯都被释放了");
    }


}

猜你喜欢

转载自blog.csdn.net/qq_40995238/article/details/115002526
今日推荐