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