/**
* 十只老鼠试验一千瓶药水,只有一瓶有毒,怎么找出有毒的那瓶?
*
* 1000,转为二进制为11 1110 1000,共十位,每只老鼠各对应一位,
* 比如3的二进制为0011,第1、2上为1,就让第1、2只老鼠都喝编号为3的药水,
* 8的二进制为1000,第4位上为1,就让第4只老鼠喝编号为8的药水 ...
* 15的二进制为1111,1到4位都为1,就让第1、2、3、4只老鼠都喝编号为15的药水
* 1000的二进制为11 1110 1000,就是第4、6、7、8、9、10只老鼠老要喝编号为1000的药水
* 每瓶药水都试完后,通过老鼠有没有喝药水就可以把1到1000所有的数字表示出来
*
* 喝了,则这只老鼠所在位上就为1,没喝就为0
*
* 像上面示例中,第15瓶药水有毒则第1、2、3、4只老鼠中毒,
* 第8瓶药水有毒则只有第4只老鼠中毒,
* 第3瓶药水有毒则第1、2只老鼠中毒
*/
public static void main(String[] args) {
//给每只老鼠编号,且各自对应一个集合
Map<Integer, List<String>> mouseMap = new HashMap<>();
for (int i = 1; i <= 10; i++) {
mouseMap.put(i,Lists.newArrayList());
}
//把药水进行编号,并转为二进制,二进制最多十位,
// 第一只老鼠对应二进制的第一位,第二只对应第二位.........第十只对应第十位
// 药水编号的二进制哪一位上有1,就让那一位上对应的老鼠喝掉这个编号的药水
//比如,1101,第一、三、四位上为1,那1、3、4号老鼠就要喝这瓶药水
for (int i = 1; i <= 1000; i++) {
String s = Integer.toBinaryString(i);
for (int j = 1; j < 11; j++) {
List<String> list = mouseMap.get(j);
if(s.length() >= j && s.charAt(s.length() - j) == '1'){
list.add(s);
}
}
}
//把有毒的药水编号转为二进制,那么这个二进制上哪一位上为1的对应编号的老鼠就会死掉
//如果第43瓶,转为二进制为10 1011,则第一、二、四、六只老鼠会中毒
// 最后执行结果为mouse1、mouse2、mouse4、mouse6
String s = Integer.toBinaryString(43);
for (int j = 1; j < 11; j++) {
List<String> list = mouseMap.get(j);
if(list.contains(s)){
System.out.println("mouse"+j);
}
}
}
十只老鼠在1000瓶药水中找一瓶有毒的
于 2022-11-12 17:26:19 首次发布