1000瓶水其中有一瓶水有毒,有10只老鼠并且只要老鼠喝了有毒的水必死。请问怎样通过一次实验找出有毒的那瓶水。
程序员文章站
2024-03-22 13:30:46
...
1000瓶水其中有一瓶水有毒,有10只老鼠并且只要老鼠喝了有毒的水必死。请问怎样通过一次实验找出有毒的那瓶水。
. 这道题知识点:二进制。
解题思路:2的10次方等于1024,1024以内的所有自然数都可以用10个数位的二进制数表示出来。1000 <= 1024,此题可解。
第一步:将1000瓶水从water[0]到water[999]分别进行编号,并转化成10个数位的二进制数表示如下:
第二步:将10只老鼠从mouse[0]到mouse[9]进行编号
0.让第mouse[0]只老鼠喝第0位为1的所有的水
1.让第mouse[1]只老鼠喝第1位为1的所有的水
2.让第mouse[2]只老鼠喝第2位为1的所有的水
.
.
.
8.让第mouse[8]只老鼠喝第8位为1的所有的水
9.让第mouse[9]只老鼠喝第9位为1的所有的水
这样就保证了(除了第0瓶水外)每一瓶水都有老鼠喝了。
第三步:根据老鼠的存活情况判定有毒水方法
if(如果第i只老鼠死了) 则让 water[第i位1的水的编号]的值-1.
else 则让 water[第i位1的水的编号]的值+1.
然后找出wanrer[0]--water[999] 中 的最小数water[i],
if(water[i] <0) 即为 第 i 瓶水有毒 else 为第0瓶水有毒。
原因:因为water[0]--water[999]的初始值都为0,如果第i只老鼠死了,说明第mouse[i]只老鼠喝的水中必有一瓶有毒,所以令 water[第i位1的水的编号]的值各-1.如果第i只老鼠没有死,说明第mouse[i]只老鼠喝的水都没有毒,所以令 water[第i位1的水的编号]的值各+1。
import java.util.Arrays;
import java.lang.StringBuilder;
import java.util.Scanner;
public class toxicWater {
public static final int waterNumber = 1000;//水的数目
public static final int mouseNumber = 10;//老鼠的数目
public static void main(String args[]){
int water[] = new int[waterNumber];
int mouse[] = new int[mouseNumber];
int i,j;
String s;
StringBuffer sb;
int flag = 1;
Scanner reader = new Scanner(System.in);
// System.out.println("请输入老鼠的存活情况,1 表示死了,0表示还活着:");
for( i=0; i<mouseNumber; i++){
System.out.println("请输入第"+i+"老鼠的存活情况(1 表示死了,0表示还活着)");
mouse[i] = reader.nextInt();
}
for( i=0; i<mouseNumber; i++ ){//mouseNumber只老鼠
for( j=0; j<waterNumber; j++ ){//1000瓶水
s = Long.toBinaryString(j);//将 j 转换为二进制
sb = new StringBuffer(s);
sb.reverse();//将字符串反转
if( sb.length() >= i+1 ){//字符串长度
if( mouse[i] == 1 ){//老鼠死了
if( sb.charAt(i) == '1'){//第i只老鼠喝了第j瓶水
water[j]--;
}
}
else{//老鼠未死
if( sb.charAt(i) == '1'){
water[j]++;
}
}
}
}
}
int min = 0;
for( i=0; i<waterNumber; i++ ){//找出数值最小的water
if( water[i] < min ){
min = water[i];
flag = i;
}
}
if( min < 0 ){
System.out.println("第瓶"+flag+"瓶水有毒!!!");
}
else{
System.out.println("第瓶0瓶水有毒!!!");
}
}
}