Liny_@NotePad

沉迷ACG中

国王和100个囚犯

YOYO posted @ 2010年1月14日 03:34 in 【Java SE】 , 2218 阅读

一道益智题:

国王招来100个囚犯,对他们说:你们犯的是死罪,本应该将你们统统杀掉,但我慈悲为怀,给你们一次求生的机会。15分钟以后,你们将被关进一个有100间隔离牢房的监狱里,每人一间牢房,都与外界隔绝,什么也听不见、看不到,连时间都没法计算,更别说获得外界的任何信息。(送饭除外,但也是不规律的送)

这所监狱有一个院子,每天会随机(注意是完全随机)打开一间牢房的门,让那个囚犯到院子里来放风。院子里有一盏路灯,放风的囚犯可以控制它的开关,将它打开或是关闭。除囚犯之外,其他人都不会去碰开关。这盏灯会永远有充足的能源供应,如果灯泡坏了或是电路出了故障会马上修好,当然修理人员不会改变灯的状态(开或关)。

除了开关这盏灯,放风的囚犯放风时留下的任何其它痕迹都会在夜晚被清除干净(包括在灯上作的任何记号)。

牢房是完全封闭的,院子里的灯光在牢房里看不到。只有放风出到院子里的人才能看到。

好了现在我向你们提出一个要求,只要你们做到了,就可以全部获得释放: 若干天以后,你们中只要有任何一个人能够向我证明所有的人都曾到院子里去过,你们就全体释放。当然要有证据!因为我只会给你们一次机会,如果向我证明的那个人无法自圆其说,你们就全部砍头。所以,要珍惜这次机会。如果你们永远做不到我的要求,你们就全部关到死。

现在给你们15分钟商量你们的方案。15分钟以后,你们将被关进我刚才说的那个监狱,永远无法再交流。

大家试着用程序试下:D

我测试出来的结果是

总共花费27年82天
总共花费26年358天
总共花费28年60天
总共花费22年276天
总共花费27年152天
总共花费31年251天
总共花费28年282天
总共花费28年214天
总共花费32年156天
总共花费31年296天

真是群可怜的娃子 - -……

顺便贴个代码,首先是灯:

package org.yoyo.prison;

/**
 * 灯
 * @author YOYO
 *
 */
public class Light {
	
	/**
	 * 状态
	 */
	private boolean state = false;
	
	public void changeState(boolean state) {
		if (state) {
			System.out.println("点亮了灯");
		} else {
			System.out.println("熄灭了灯");
		}
		this.state = state;
	}
	
	public boolean getState() {
		return this.state;
	}

}

然后是囚犯:

package org.yoyo.prison;

/**
 * 囚犯
 * @author YOYO
 *
 */
public abstract class Prisoner {
	
	protected int prisonerId;
	
	public Prisoner(int prisonerId) {
		this.prisonerId = prisonerId;
	}
	
	/**
	 * 询问
	 */
	public abstract boolean wantProve();

	/**
	 * 改变灯的状态
	 */
	public abstract void changeLightState(Light light);
	
}

普通囚犯:

package org.yoyo.prison;

/**
 * 普通囚犯
 * @author YOYO
 *
 */
public class OrdinaryPrisoner extends Prisoner {
	
	private boolean doFlag = false;

	public OrdinaryPrisoner(int prisonerId) {
		super(prisonerId);
	}

	@Override
	public void changeLightState(Light light) {
		if (light.getState() && !doFlag) {
			doFlag = true;
			light.changeState(false);
		} else {
			System.out.println("不做任何操作");
		}
	}

	@Override
	public boolean wantProve() {
		return false;
	}

}

计数的囚犯:

package org.yoyo.prison;

/**
 * 计数囚犯
 * @author YOYO
 *
 */
public class CounterPrisoner extends Prisoner {
	
	/**
	 * 计数
	 */
	private int count = 0;
	
	/**
	 * 囚犯总数
	 */
	private int total;

	public CounterPrisoner(int prisonerId, int total) {
		super(prisonerId);
		this.total = total;
	}

	@Override
	public void changeLightState(Light light) {
		if (light.getState() == false) {
			++count;
			light.changeState(true);
		} else {
			System.out.println("不做任何操作");
		}
	}

	@Override
	public boolean wantProve() {
		return count == total;
	}

}

测试:

package org.yoyo.prison;

public class TestMain {
	
	private final static int NUMBER = 100;
	
	public static void main(String[] args) {
		Light light = new Light();
		Prisoner[] prisoners = new Prisoner[NUMBER];
		prisoners[0] = new CounterPrisoner(0, NUMBER);
		for (int i = 1; i < NUMBER; ++i) {
			prisoners[i] = new OrdinaryPrisoner(i);
		}
		
		int times = 0;
		while (true) {
			++times;
			int num = (int) (Math.random() * NUMBER);
			System.out.print(num + "号囚犯 ");
			prisoners[num].changeLightState(light);
			if (prisoners[num].wantProve()) {
				System.out.println(NUMBER + "个囚犯已经都出去过一次!");
				break;
			}
		}
		
		System.out.println("总共花费" + times / 365 + "年" + times % 365 + "天");
	}

}
  • 无匹配

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter