5个钢珠离开凹轨的最短时间和最长时间

问题:在一个长为33厘米的光滑凹轨上,在第3厘米、第6厘米、第19厘米、第22厘米、第26厘米处各有一个钢珠,凹轨很细,不能同时通过两个钢珠,开始时,钢珠运动方向是任意的。两个钢珠相撞后,以相同速度反向运动。假设所有钢珠初始速度为每秒运动1厘米,那么所有钢珠离开凹轨的最短和最长时间是多少?



分析:5个钢珠的移动方向都有两种可能:向左或者向右。这样钢珠运动的组合就有2的5次方,也就是32种。


最少时间是:14

最大时间是:30

第1种情况的初始方向是:  Left  Left  Left  Left  Left -- 花费的时间是:26

第2种情况的初始方向是:  Right  Left  Left  Left  Left -- 花费的时间是:30

第3种情况的初始方向是:  Left  Right  Left  Left  Left -- 花费的时间是:27

第4种情况的初始方向是:  Right  Right  Left  Left  Left -- 花费的时间是:30

第5种情况的初始方向是:  Left  Left  Right  Left  Left -- 花费的时间是:26

第6种情况的初始方向是:  Right  Left  Right  Left  Left -- 花费的时间是:30

第7种情况的初始方向是:  Left  Right  Right  Left  Left -- 花费的时间是:27

第8种情况的初始方向是:  Right  Right  Right  Left  Left -- 花费的时间是:30

第9种情况的初始方向是:  Left  Left  Left  Right  Left -- 花费的时间是:26

第10种情况的初始方向是:  Right  Left  Left  Right  Left -- 花费的时间是:30

第11种情况的初始方向是:  Left  Right  Left  Right  Left -- 花费的时间是:27

第12种情况的初始方向是:  Right  Right  Left  Right  Left -- 花费的时间是:30

第13种情况的初始方向是:  Left  Left  Right  Right  Left -- 花费的时间是:26

第14种情况的初始方向是:  Right  Left  Right  Right  Left -- 花费的时间是:30

第15种情况的初始方向是:  Left  Right  Right  Right  Left -- 花费的时间是:27

第16种情况的初始方向是:  Right  Right  Right  Right  Left -- 花费的时间是:30

第17种情况的初始方向是:  Left  Left  Left  Left  Right -- 花费的时间是:22

第18种情况的初始方向是:  Right  Left  Left  Left  Right -- 花费的时间是:30

第19种情况的初始方向是:  Left  Right  Left  Left  Right -- 花费的时间是:27

第20种情况的初始方向是:  Right  Right  Left  Left  Right -- 花费的时间是:30

第21种情况的初始方向是:  Left  Left  Right  Left  Right -- 花费的时间是:22

第22种情况的初始方向是:  Right  Left  Right  Left  Right -- 花费的时间是:30

第23种情况的初始方向是:  Left  Right  Right  Left  Right -- 花费的时间是:27

第24种情况的初始方向是:  Right  Right  Right  Left  Right -- 花费的时间是:30

第25种情况的初始方向是:  Left  Left  Left  Right  Right -- 花费的时间是:19

第26种情况的初始方向是:  Right  Left  Left  Right  Right -- 花费的时间是:30

第27种情况的初始方向是:  Left  Right  Left  Right  Right -- 花费的时间是:27

第28种情况的初始方向是:  Right  Right  Left  Right  Right -- 花费的时间是:30

第29种情况的初始方向是:  Left  Left  Right  Right  Right -- 花费的时间是:14

第30种情况的初始方向是:  Right  Left  Right  Right  Right -- 花费的时间是:30

第31种情况的初始方向是:  Left  Right  Right  Right  Right -- 花费的时间是:27

第32种情况的初始方向是:  Right  Right  Right  Right  Right -- 花费的时间是:30

//方向枚举类
public enum Direction {

	RIGHT, LEFT;

	public boolean isRight() {
		return RIGHT == this;
	}

	public boolean isLeft() {
		return LEFT == this;
	}

}


//钢珠球类
public class Ball {

	/*
	 * 
	 * 钢球所在的位置
	 * 
	 */

	private int location;

	/*
	 * 
	 * 钢球移动的方向
	 * 
	 */

	private Direction direction;

	/*
	 * 
	 * 钢球是否已经滚落凹轨
	 * 
	 */

	private boolean completed = false;

	public Ball() {
	}

	public Ball(int location, Direction direction) {
		this.location = location;
		this.direction = direction;
	}

	/**
	 * 
	 * 钢球移动
	 * 
	 */

	public void move() {

		if (!completed) {
			if (direction.isRight()) {
				location += 1;

			} else if (direction.isLeft()) {
				location -= 1;

			}

			/**
			 * 
			 * 在一个长为33厘米的光滑凹轨上,在第3厘米、第6厘米、第19厘米、第22厘米、第26厘米处各有一个钢珠,
			 * 
			 */

			if (location <= 0 || location >= 33) {
				completed = true;
			}
		}
	}

	/**
	 * 
	 * 判断钢球的位置是否有冲突。
	 * 
	 */

	public boolean isLocationConfilict(Ball ant) {
		return this.location == ant.location;
	}

	/**
	 * 
	 * 当钢球位置冲突的时候,需要转换钢球的方向。
	 * 
	 */

	public void changeDirection() {

		switch (direction) {

		case RIGHT:
			direction = Direction.LEFT;
			break;

		case LEFT:
			direction = Direction.RIGHT;
			break;

		default:
			break;

		}

	}

	/**
	 * 
	 * @return the completed
	 * 
	 */

	public boolean isCompleted() {

		return completed;

	}

	/**
	 * 
	 * @param completed
	 * 
	 * the completed to set
	 * 
	 */

	public void setCompleted(boolean completed) {

		this.completed = completed;

	}

	/**
	 * 
	 * @return the direction
	 * 
	 */

	public Direction getDirection() {

		return direction;

	}

	/**
	 * 
	 * @param direction
	 * 
	 * the direction to set
	 * 
	 */

	public void setDirection(Direction direction) {

		this.direction = direction;

	}

	/**
	 * 
	 * @return the location
	 * 
	 */

	public int getLocation() {

		return location;

	}

	/**
	 * 
	 * @param location
	 * 
	 * the location to set
	 * 
	 */

	public void setLocation(int location) {

		this.location = location;

	}

}


//钢球移动的场景类

/**
 * 在一个长为33厘米的光滑凹轨上,在第3厘米、第6厘米、第19厘米、第22厘米、第26厘米处各有一个钢珠,
 * 凹轨很细,不能同时通过两个钢珠,开始时,钢珠运动方向是任意的。两个钢珠相撞后,以相同速度反向运动。
 * 假设所有钢珠初始速度为每秒运动1厘米,那么所有钢珠离开凹轨的最短和最长时间是多少?
 */

public class BallMoveScene {

	/*
	 * 5只钢球的初始位置
	 */

	private static int[] locations = { 3, 6, 19, 22, 26 };

	private int minElapsedTime = 0;

	private int maxElapsedTime = 0;

	public void proceed() {
		for (int i = 0; i < 32; i++) {
			
			Ball[] balls = buildInitializedBalls(initialDirections(i));
			
			printInitialDirections(balls, i);
			
			int elapsedTime = 0;
			
			while (!isAllBallsCompleted(balls)) {
				move(balls);
				handleLocationConfilict(balls);
				elapsedTime++;
			}

			System.out.println("-- 花费的时间是:" + elapsedTime);

			if (minElapsedTime == 0 || (elapsedTime < minElapsedTime)) {

				minElapsedTime = elapsedTime;

			}

			if (maxElapsedTime == 0 || (elapsedTime > maxElapsedTime)) {

				maxElapsedTime = elapsedTime;

			}

		}

		System.out.println("最少时间是:" + minElapsedTime);

		System.out.println("最大时间是:" + maxElapsedTime);

	}

	/**
	 * 
	 * 输出第n种的钢珠初始化方向。
	 * 
	 */

	private void printInitialDirections(Ball[] balls, int n) {

		System.out.print("第" + (n + 1) + "种情况的初始方向是: ");

		for (Ball ball : balls) {

			System.out.print(ball.getDirection().isLeft() ? " Left "

			: " Right ");

		}

	}

	/**
	 * 
	 * 判断是否有钢珠位置冲突, 如果位置有冲突,那么这两只钢珠的方向将改变。
	 * 
	 */

	private void handleLocationConfilict(Ball[] balls) {

		for (int i = 0; i < balls.length; i++) {
			for (int j = i + 1; j < balls.length; j++) {
				if (balls[i].isLocationConfilict(balls[j])) {
					balls[i].changeDirection();
					balls[j].changeDirection();
				}
			}
		}
	}

	/**
	 * 
	 * 钢珠移动
	 * 
	 */

	private void move(Ball[] balls) {
		for (Ball ball : balls) {
			ball.move();
		}
	}

	/**
	 * 
	 * 5只钢珠,每只钢珠可以向左(朝0的方向走),也可以向右(朝27的方向走), 这样的话有2的5次方,也就是32种情况。
	 * 
	 * 可以从0~31来遍历,初始化钢珠的开始位置 0代码向左,1代码向右。
	 * 
	 */

	private Direction[] initialDirections(int value) {

		int[] result = new int[5];

		result[0] = value % 2;

		result[1] = value / 2 % 2;

		result[2] = value / 4 % 2;

		result[3] = value / 8 % 2;

		result[4] = value / 16 % 2;

		Direction[] directions = new Direction[result.length];

		for (int i = 0; i < result.length; i++) {

			if (0 == result[i]) {

				directions[i] = Direction.LEFT;

			} else {

				directions[i] = Direction.RIGHT;

			}

		}

		return directions;

	}

	/**
	 * 
	 * @param directions
	 * 
	 * 初始化的方向
	 * 
	 * @return 返回初始化5个钢球的最初状态,包括初始化的位置以及初始化的方向。
	 * 
	 */

	private Ball[] buildInitializedBalls(Direction[] directions) {

		Ball[] Balls = new Ball[5];
		for (int i = 0; i < 5; i++) {
			Balls[i] = new Ball(locations[i], directions[i]);
		}

		return Balls;

	}

	/**
	 * 
	 * 判断所有的钢球是否都离开凹轨
	 * 
	 */

	private boolean isAllBallsCompleted(Ball[] Balls) {

		for (Ball Ball : Balls) {
			if (!Ball.isCompleted()) {
				return false;
			}
		}
		return true;
	}

}


//测试类
public class Test {
	
	public static void main(String[] args) {

		new BallMoveScene().proceed();

	}

}


测试结果:
第1种情况的初始方向是:  Left  Left  Left  Left  Left -- 花费的时间是:26
第2种情况的初始方向是:  Right  Left  Left  Left  Left -- 花费的时间是:30
第3种情况的初始方向是:  Left  Right  Left  Left  Left -- 花费的时间是:27
第4种情况的初始方向是:  Right  Right  Left  Left  Left -- 花费的时间是:30
第5种情况的初始方向是:  Left  Left  Right  Left  Left -- 花费的时间是:26
第6种情况的初始方向是:  Right  Left  Right  Left  Left -- 花费的时间是:30
第7种情况的初始方向是:  Left  Right  Right  Left  Left -- 花费的时间是:27
第8种情况的初始方向是:  Right  Right  Right  Left  Left -- 花费的时间是:30
第9种情况的初始方向是:  Left  Left  Left  Right  Left -- 花费的时间是:26
第10种情况的初始方向是:  Right  Left  Left  Right  Left -- 花费的时间是:30
第11种情况的初始方向是:  Left  Right  Left  Right  Left -- 花费的时间是:27
第12种情况的初始方向是:  Right  Right  Left  Right  Left -- 花费的时间是:30
第13种情况的初始方向是:  Left  Left  Right  Right  Left -- 花费的时间是:26
第14种情况的初始方向是:  Right  Left  Right  Right  Left -- 花费的时间是:30
第15种情况的初始方向是:  Left  Right  Right  Right  Left -- 花费的时间是:27
第16种情况的初始方向是:  Right  Right  Right  Right  Left -- 花费的时间是:30
第17种情况的初始方向是:  Left  Left  Left  Left  Right -- 花费的时间是:22
第18种情况的初始方向是:  Right  Left  Left  Left  Right -- 花费的时间是:30
第19种情况的初始方向是:  Left  Right  Left  Left  Right -- 花费的时间是:27
第20种情况的初始方向是:  Right  Right  Left  Left  Right -- 花费的时间是:30
第21种情况的初始方向是:  Left  Left  Right  Left  Right -- 花费的时间是:22
第22种情况的初始方向是:  Right  Left  Right  Left  Right -- 花费的时间是:30
第23种情况的初始方向是:  Left  Right  Right  Left  Right -- 花费的时间是:27
第24种情况的初始方向是:  Right  Right  Right  Left  Right -- 花费的时间是:30
第25种情况的初始方向是:  Left  Left  Left  Right  Right -- 花费的时间是:19
第26种情况的初始方向是:  Right  Left  Left  Right  Right -- 花费的时间是:30
第27种情况的初始方向是:  Left  Right  Left  Right  Right -- 花费的时间是:27
第28种情况的初始方向是:  Right  Right  Left  Right  Right -- 花费的时间是:30
第29种情况的初始方向是:  Left  Left  Right  Right  Right -- 花费的时间是:14
第30种情况的初始方向是:  Right  Left  Right  Right  Right -- 花费的时间是:30
第31种情况的初始方向是:  Left  Right  Right  Right  Right -- 花费的时间是:27
第32种情况的初始方向是:  Right  Right  Right  Right  Right -- 花费的时间是:30
最少时间是:14
最大时间是:30

你可能感兴趣的:(java)