有一根27厘米的细木杆,在第3厘米、7厘米、11厘米、17厘米、23厘米这五个位置上各有一只蚂蚁。 木杆很细,不能同时通过一只蚂蚁。开始 时,蚂蚁的头朝左还是朝右是任意的,它们只会朝前走或调头, 但不会后退。当任意两只蚂蚁碰头时,两只蚂蚁会同时调头朝反方向走。假设蚂蚁们每秒钟可以走一厘米的距离。 编写程序,求所有蚂蚁都离开木杆 的最小时间和最大时间。
看到这道题感觉可以将前几天遇到的小白鼠验毒药问题的思想拿来用一下,因为一开始蚂蚁朝左朝右的位置不确定,所以需要有一种方法来描述蚂蚁头的位置。因为一只蚂蚁要么朝右要么朝左,一共有五只蚂蚁,我们可以用一个五位的2进制数字来表示这五个蚂蚁一开始头的方向。例如:00001(其中0代表朝右,1代表朝左)代表第一只蚂蚁头朝右,第二只蚂蚁头朝右......第五只蚂蚁头朝左,依次类推一直到11111,得到五只蚂蚁在木棍上所有头朝向的组合,进行一次循环。用hashmap存储蚂蚁的序号及其位置,蚂蚁每离开一只,便将其从hashmap中移走,直到所有蚂蚁离开。由于所有蚂蚁都在奇数的位置上,故不可能出现两个蚂蚁在半厘米处相遇的情况。算法中还必须有一个计数器,当所有蚂蚁都移动了一厘米的位置的时候计数器便+1,用来计算蚂蚁移动的时间。如果时间比MINTIME小,便将这个时间保存。如果时间比MAXTIME大,也将这个记录保存。最后得出蚂蚁离开的最大和最小时间。一下是此程序的java代码:
import java.util.HashMap;
public class TestBaiduAnt {
public static void move(HashMap hm,char[] chs){
for(int i=0;i<chs.length;i++){
int num=Integer.parseInt(chs[i]+"");
Integer num2=(Integer)hm.get(i+1);
int s=num2;
if(num==0){
s+=1;
hm.remove(i+1);
hm.put(i+1,s);
}else{
s-=1;
hm.remove(i+1);
hm.put(i+1,s);
}
}
}
public static void MeetAndRevertion(HashMap hm,char[] chs){
for(int i=1;i<5;i++){
for(int j=i+1;j<=5;j++){
int in=(Integer)hm.get(i);
int in2=(Integer)hm.get(j);
if(in==in2){
if(Integer.parseInt(chs[i-1]+"")==0){
chs[i-1]='1';
chs[j-1]='0';
}else{
chs[i-1]='0';
chs[j-1]='1';
}
}
}
}
}
public static String LeftZero(String value,int len){
if(value.length()<len){
int minus=len-value.length();
for(int i=0;i<minus;i++){
value="0"+value;
}
}
return value;
}
public static boolean CheckLeaveAll(HashMap hm){
boolean result=false;
int count=0;
for(int i=1;i<=5;i++){
Integer in=(Integer)hm.get(i);
if(in<=0||in>=27){
count++;
}
}
if(count==5){
result=true;
}
return result;
}
public static void main(String[] args){
int MAXTIME=0;
int MINTIME=9999999;
char[] minlocation=null;
char[] maxlocation = null;
for(int i=1;i<32;i++){
HashMap hm=new HashMap();
hm.put(1,3);
hm.put(2,7);
hm.put(3,11);
hm.put(4,17);
hm.put(5,23);
int time=0;
String nums=Integer.toString(i,2);
String num=LeftZero(nums,5);
char[] chs=num.toCharArray();
while(!CheckLeaveAll(hm)){
time++;
move(hm, chs);
MeetAndRevertion(hm, chs);
}
if(time<MINTIME){
MINTIME=time;
minlocation=chs;
}else if(time>MAXTIME){
MAXTIME=time;
maxlocation=chs;
}
}
System.out.println("0代表头朝右,1代表头朝左");
System.out.println("最长时间为:"+MAXTIME);
for(int i=0;i<5;i++){
System.out.print("当为最长时间时第"+(i+1)+"个蚂蚁头的方向为:"+maxlocation[i]+" ");
}
System.out.println();
System.out.println("最短时间为:"+MINTIME);
for(int i=0;i<5;i++){
System.out.print("当为最短时间时第"+(i+1)+"个蚂蚁头的方向为:"+minlocation[i]+" ");
}
}
}