蚂蚁爬杆问题--面向对象,建模


 * 有一根27厘米的细木杆,在第3厘米、7厘米、11厘米、18厘米、23厘米这五个位置上各有一只蚂蚁。
 * 木杆很细,不能同时通过两只蚂蚁。开始时,蚂蚁的头朝左还是朝右是任意的,它们只会朝前走或调头,但不会后退。
 * 当任意两只蚂蚁碰头时,两只蚂蚁会同时调头朝反方向走。假设蚂蚁们每秒钟可以走一厘米的距离。编写程序,求所有蚂蚁都离开木杆的最小时间和最大时间。
 * 
 * 要求:用类模拟出蚂蚁的行为特性,进而模拟出五只蚂蚁在木杆上的运行过程来编程求解。不能通过数学的方式直接用公式计算。


 
public class AntMove {
	public static void main(String[] args) {
		int a[]={3,7,11,18,23};
		Ant ants[]=new Ant[a.length];
		Ant.setANT_NUM(a.length);
		
		int numOfDirectionStates=1;
		for(int i=0;i<a.length;i++){
			numOfDirectionStates*=2;
		}
		for(int i=0;i<a.length;i++){
			ants[i]=new Ant(numOfDirectionStates);
		}
		
		//把蚂蚁所有可能的移动方向的情况存在 directionStates[32][5]里 。行代表第几种情况,列代表第几只蚂蚁的方向
		boolean directionStates[][]=new boolean[numOfDirectionStates][a.length];
		for(int i=0;i<numOfDirectionStates;i++){
			for(int j=0;j<a.length;j++){
				/*
				directionStates[i][0]= ( (i&1)==0 ) ;
				directionStates[i][1]= ( (i&2)==0 ) ;
				directionStates[i][2]= ( (i&4)==0 ) ;
				directionStates[i][3]= ( (i&8)==0 ) ;
				directionStates[i][4]= ( (i&16)==0 ) ;
				*/
				directionStates[i][j]=( (i&(1<<j) )==0 );
			}
		}
		//进行暴力搜索,--就是对每一种蚂蚁移动情况 进行测试
		for(int i=0;i<numOfDirectionStates;i++){
			//先初始化 蚂蚁属性
			for(int j=0;j<a.length;j++){
				ants[j].setDown(false);
				ants[j].setLeft(directionStates[i][j]);
				ants[j].setPos(a[j]);
			}
			Ant.setNumOfDown(0);
			Ant.setTime(0);
			
			while(true){
				print(ants);
				Ant.timeMove();		//每循环一次,时间增加1
				
				//每只蚂蚁走一步
				for(int j=0;j<a.length;j++){
					ants[j].move(1);
				}
				
				//先让蚂蚁走一步,然后在考虑碰头与撞头的情况
				for(int j=0;j<a.length-1;j++){
					if(!ants[j].isLeft() && ants[j+1].isLeft() &&
							!ants[j].isDown() && !ants[j+1].isDown()){
						//碰头
						if(ants[j].getPos()==ants[j+1].getPos()){
							System.out.println("发生碰头,掉头走");
							ants[j].turnRound();
							ants[j+1].turnRound();
						}
						
						//撞头
						if(ants[j].getPos()>ants[j+1].getPos()){
							//这一步无效,并改变方向
							System.out.println("发生撞头,这步无效,回退一步,掉头走");
							ants[j].move(-1);
							ants[j+1].move(-1);
							ants[j].turnRound();
							ants[j+1].turnRound();
						}
					}
				}
				
				if(Ant.getNumOfDown()==a.length){
					//当所有蚂蚁全部掉下杆子时,跳出循环,执行下一种情况
					break;
				}
			}
		}
		int times[]=Ant.getTimes();
		System.out.println("最终结果:");
		System.out.println("minTime="+Ant.getMinTime());
		System.out.println("最短时间掉下杆子的各个蚂蚁运动情况如下:");
		int count=0;
		for(int i=0;i<times.length;i++){
			if( times[i]==Ant.getMinTime() ){
				System.out.println("第"+(++count)+"种");
				for(int j=0;j<ants.length;j++){
					if(directionStates[i][j]){
						System.out.println("第"+(j+1)+"个球往左");
					}else{
						System.out.println("第"+(j+1)+"个球往右");
					}
				}
			}
		}
		System.out.println();
		System.out.println("maxTime="+Ant.getMaxTime());
		System.out.println("最长时间掉下杆子的各个蚂蚁运动情况如下:");
		count=0;
		for(int i=0;i<times.length;i++){
			if( times[i]==Ant.getMaxTime() ){
				System.out.println("第"+(++count)+"种");
				for(int j=0;j<ants.length;j++){
					if(directionStates[i][j]){
						System.out.println("第"+(j+1)+"个球往左");
					}else{
						System.out.println("第"+(j+1)+"个球往右");
					}
				}
			}
		}
	}


	private static void print(Ant ants[]) {
		// TODO Auto-generated method stub
		boolean isFirst=true;
		for(int i=0;i<ants.length;i++){
			if(isFirst){
				isFirst=false;
				System.out.print(ants[i].getPos());
			}else{
				System.out.print(", "+ants[i].getPos());
			}
		}
		System.out.println();
	}
}


class Ant{
	public final static int LEFT_END=0;
	public final static int RIGHT_END=0;
	private static int numOfDown;	//掉下了几只蚂蚁
	private static int time;
	private static int ANT_NUM;		//总共有几只蚂蚁
	private static int minTime=Integer.MAX_VALUE;
	private static int maxTime=-1;
	
	private static int times[];
	private static int count;
	


	
	private boolean left;		//蚂蚁移动方向
	private int pos;		//蚂蚁位置
	private boolean down;		//蚂蚁是否落下
	
	public Ant(int a) {
		// TODO Auto-generated constructor stub
		times=new int[a];
	}
	/*
	public Ant(int location,boolean left) {
		this.location=location;
		this.isLeave=false;
		this.left=left;
		//生成一个从1970年1月1日到当前时间的毫秒数 System.currentTimeMillis()
//		if(System.currentTimeMillis()%2==0){
//			left=true;
//		}else{
//			left=false;
//		}
	}
	*/
	public void move(int n){
		//没有掉下杆子才移动
		if(!down){
			if(left){
				pos-=n;
			}else{
				pos+=n;
			}
			
			if(pos<=0||pos>=27){
				down=true;
				numOfDown++;
				if(numOfDown==ANT_NUM){
					System.out.println("蚂蚁全部掉下去了");
					if(time<minTime){
						minTime=time;
					}
					if(time>maxTime){
						maxTime=time;
					}
					times[count]=time;
					count++;
					System.out.println("用去时间为:"+time);
					System.out.println("此时最小时间为:"+minTime);
					System.out.println("此时最大时间为:"+maxTime);
				}
			}
		}
	}
	
	public static int[] getTimes() {
		return times;
	}
	
	public static void setTimes(int[] times) {
		Ant.times = times;
	}
	
	public static int getNumOfDown() {
		return numOfDown;
	}


	public static void setNumOfDown(int numOfDown) {
		Ant.numOfDown = numOfDown;
	}


	public static int getTime() {
		return time;
	}


	public static void setTime(int time) {
		Ant.time = time;
	}
	
	public static void timeMove() {
		Ant.time++;
	}
	
	public static int getANT_NUM() {
		return ANT_NUM;
	}


	public static void setANT_NUM(int aNT_NUM) {
		ANT_NUM = aNT_NUM;
	}


	public static int getMinTime() {
		return minTime;
	}


	public static void setMinTime(int minTime) {
		Ant.minTime = minTime;
	}


	public static int getMaxTime() {
		return maxTime;
	}


	public static void setMaxTime(int maxTime) {
		Ant.maxTime = maxTime;
	}


	public boolean isLeft() {
		return left;
	}


	public void setLeft(boolean left) {
		this.left = left;
	}


	public int getPos() {
		return pos;
	}


	public void setPos(int location) {
		this.pos = location;
	}


	public boolean isDown() {
		return down;
	}


	public void setDown(boolean down) {
		this.down = down;
	}
	
	public void turnRound(){
		//改变蚂蚁的方向
		left=!left;
	}
	
}


  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值