蚂蚁过杆问题(二) ------java面向对象处理

4 篇文章 0 订阅

 问题:有一根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.");
	}
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值