搬运知乎上的一个答案和思路
一起看看
思路:
作者:大胃王
链接:https://www.
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
首先就是前提条件,有50个牢房,其中一个是老爷爷,你也可以把他当成你自己,也就是主视角。其它的都是葫芦娃,他们会提前和你商量好对策,商量好对策之后你们就被关进牢房了,谁也见不到谁,但是他们会完全服从你们之前商量好的对策并按计划执行,你们之间的沟通工具只有那一块石板。然后是规则,每天随机打开一扇门(注意这里是随机,而不是依次),只有一个人能出来放风,并且可以选择翻动石板或者是啥也不干(因为其它的东西都会被清除,所以可以理解为啥也不干),翻动几次石板都可以,但石板只有两面,也就可以理解成true和false,你可以重新将石板赋值为true或false。最后根据上面所说的前提条件和规则,让老爷爷(也就是你自己)想出一个方法,计算出多少天之后可以确定其余49个葫芦娃都还活着(为什么是活着而不是死了后面会说)。由于是随机开门,所以这个天数不确定,所以需要模拟10次最后求出平均值。
问题说完了,然后说说我想到的解决办法:
首先将石板看作一个标志位,他只有两面,我们就将一面提前约定为true,另一面约定为false,并假定初始值为false。然后我们规定,而老爷爷放风的时候,如果是true,就改为false;如果是false,就啥也不干。葫芦娃们放风的时候,如果是false,就改为true;如果是true,就啥也不干;如果之前修改过标识位,则不管是true还是false,都啥也不干。这样每个葫芦娃修改标志位之后老爷爷都会知道,当修改次数达到49的时候,老爷爷就知道其余的葫芦娃都还活着了。这其中有两个关键的问题,一个就是因为开门的随机性,只能确定其余葫芦娃还活着,这种方法无法得知有葫芦娃死了,只能说有葫芦娃死亡的可能性;还有一个问题,就是石板最开始是光滑一面朝上还是花纹一面朝上必须确定,如果不确定,那老爷爷就可能会算出50个葫芦娃来。
程序代码:
import org.junit.Test;
import java.math.BigDecimal;
import java.util.*;
public class JavaTest {
@Test
public void test() {
int count = 0;
for (int i = 0; i < 10; i++) {
List<Map<String, Object>> list = new ArrayList<>();
for (int j = 0; j < 50; j++) {
Map<String, Object> map = new HashMap<>();
if (j == 0) {
map.put("count", 0);
map.put("name", "老爷爷");
} else {
map.put("count", j);
map.put("flag", true);
map.put("name", "葫芦娃" + j);
}
list.add(map);
}
count += test1(list);
}
BigDecimal average = BigDecimal.valueOf(count).divide(BigDecimal.valueOf(10), 2, BigDecimal.ROUND_HALF_UP);
System.out.println("平均值是:" + average);
}
private int test1(List<Map<String, Object>> list) {
int count = 1;
boolean flag = false;
int alive = 0;
while (true) {
// 去1-50之间的随机数
Random random = new Random();
int i = random.nextInt(50);
Map<String, Object> person = list.get(i);
Integer personCount = (Integer) person.get("count");
if (personCount == 0) {
// 老爷爷
if (flag) {
flag = false;
alive++;
}
} else {
// 葫芦娃
if (!flag && (boolean) person.get("flag")) {
person.put("flag", false);
flag = true;
}
}
if (alive == 49) {
break;
}
count++;
}
System.out.println("第" + count + "天的时候,老爷爷知道了其余49个葫芦娃都还健在。");
return count;
}
}