问题:有一根27厘米的细木杆,在第3厘米、7厘米、11厘米、18厘米、23厘米这五个位置上各有一只蚂蚁。木杆很细,不能同时通过两只蚂蚁。开始时,蚂蚁的头朝左还是朝右是任意的,它们只会朝前走或调头,但不会后退。当任意两只蚂蚁碰头时,两只蚂蚁会同时调头朝反方向走。假设蚂蚁们每秒钟可以走一厘米的距离。编写程序,求所有蚂蚁都离开木杆的最小时间和最大时间。
思路:因为没有告诉蚂蚁的初始朝向,所以要对初始化蚂蚁朝向。用0表示朝左,1表示朝右,用二进制00000(0)表示五只蚂蚁都是朝向左,然后每次加1,直到加到11111(31)时,表示五只蚂蚁初始的所有朝向。让后随时间的推移,有些蚂蚁可能碰头,这是就的对蚂蚁的朝向就行修改,即:如原来朝向为0,则变为1,原来为1的变为0,。做到这里就会想到如何判断蚂蚁朝向问题,这个可以通过异或来解决问题。如:当要判断第一只蚂蚁朝向时,可以用二进制10000(16)与原来朝向异或,若结果为0,则表示朝向为1,朝右,否则相反;用二进制01000(8)与原来朝向异或,可以判断第二个蚂蚁的朝向,以此类推。
注意:在new一个对象数组后,还要记得对对象数组再次new,知道最后为基本类型为止。
Ant a[]=new Ant[5];
for(int i=0;i<a.length;i++){
a[i]=new Ant();
}
代码实现:
import java.util.*;
class Ant{
int direction,position;
public Ant(int d,int p){
this.set(d,p);
}
public Ant(){//令初始值为0
this.set(0,0);
}
public Ant(Ant a){
this.set(a.direction,a.position);
}
public void set(int d,int p){
this.direction=d;
this.position=p;
}
public void change(Ant a[],int n){//改变蚂蚁的初始朝向,通过加1来改变初始朝向。如:00000+1 ---> 00001,00010 ---> 00011 一直到 11111。(相当于二进制加法)
if(n<a.length){
a[n].direction+=1;
if(a[n].direction>1){//大于1时,原值变为0,并向下一位进1
a[n].direction=0;//原值变为0
change(a,n+1);//下一位进1
}
}
return ;
}
public void move(Ant a){//蚂蚁移动
if(Ant.direct(a)){//若为0,则向左移动,为1,则向右移动
a.position--;
}else{
a.position++;
}
}
public static boolean direct(Ant a){//判断蚂蚁的朝向问题
return (a.direction^1)==1;
}
public int fallNumb(Ant a[]){//记录蚂蚁掉下去的个数
int k=0;
for(int i=0;i<a.length;i++){
if(a[i].position>=27||a[i].position<=0){
k++;
}
}
return k;
}
public String toString(){
return "direction: "+this.direction+" position: "+this.position;
}
}
class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
Ant ant=new Ant();
Ant a[]=new Ant[5];
int n;
for(int i=0;i<a.length;i++){//记住 ,这里一定要在new,对于初学java的我卡死这里了<img alt="大哭" src="http://static.blog.csdn.net/xheditor/xheditor_emot/default/wail.gif" />
a[i]=new Ant();
}
for(int i=0;i<a.length;i++){
a[i].position=sc.nextInt();
a[i].direction=0;
}
Ant b[]=new Ant[5];
for(int i=0;i<b.length;i++){
b[i]=new Ant();
}
int min=99999,max=-99999,step=0;
for(int i=0;i<=31;i++){
for(int k=0;k<b.length;k++){//保留蚂蚁的初始位置,但初始朝向时改变的
b[k].position=a[k].position;
b[k].direction=a[k].direction;
}
step=0;//记录步数
ant.change(a,0);
while(true){
if(ant.fallNumb(b)==5){//若掉下的蚂蚁数为5,则结束
break;
}
step++;
for(int k=0;k<5;k++){//蚂蚁移动
ant.move(b[k]);
}
/*for(int k=0;k<b.length;k++){
System.out.print(b[k].position+" ");
}System.out.println();*/
for(int k=0;k<4;k++){//判断是否碰头
if(b[k].position==b[k+1].position){若碰头则0变1,1变0
b[k].direction=(b[k].direction)^1;
b[k+1].direction=(b[k+1].direction)^1;
}
}
}
if(step>max){
max=step;
}
if(step<min){
min=step;
}
}
System.out.println("max time= "+max+" second.");
System.out.println("min time= "+min+" second.");
}
}