今天看到一个很有趣的面试题:
有 100 个囚犯分别关在 100 间牢房里。牢房外有一个空荡荡的房间,房间里有一个由开关控制的灯泡。初始时,灯是关着的(或者随机)。看守每天随便选择一名囚犯进入房间,但保证每个囚犯都会被选中无穷多次。如果在某一时刻,有囚犯成功断定出所有人都进过这个房间了,所有囚犯都能释放。游戏开始前,所有囚犯可以聚在一起商量对策,但在此之后它们唯一可用来交流的工具就只有那个灯泡。他们应该设计一个怎样的协议呢?请根据此协议设计实现一个程序,把解题过程详细输出并给出解题所需天数。
下面说一下思路:
假设100个囚犯每天随机出去.若要每人都出去.概率是100天中每人至少有一次机会放风.那么要100个囚犯都出去得要100乘以100次.也就是大概需要10000天.10000天大概是(10000/365)等于27年.下面给出代码
import java.text.SimpleDateFormat; import java.util.Calendar;
public class LightTest { //灯的信号 public static boolean lightFlag = false; //计数器 public static int count = 0; public static void main(String[] args) throws Exception { //100个囚犯 Boolean[] array = new Boolean[100]; for (int i = 0; i < 100; i++) { array[i] = Boolean.FALSE; } //用来计算时间 Calendar calendar = Calendar.getInstance(); //计算经过的天数 int dayNum = 0; // while (count <= 99) { int ff = (int) Math.round(Math.random() * 99); // 如果犯人没有开过灯 并且灯是关着的 而且犯人不是计数的人 String localDate = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime()); //如果随机出来的不是关灯者. if (ff != 50) { //如果灯是灭的.就把灯打开,若已经是灭的.就不用管 if(!lightFlag){ lightFlag = true; array[ff] = true; } }else{ //若灯是亮的.就把灯关掉.表示有一个人已经开过灯了. if (lightFlag) { lightFlag = false; count++; } } calendar.add(Calendar.DATE,1); dayNum++; } String localDate = new SimpleDateFormat("yyyy-MM-dd").format(calendar.getTime()); System.out.println(localDate +"才把所有的灯都关掉,经过:"+dayNum); System.out.println("大约经过:"+(dayNum/365)+"年"); }