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

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

 

分析:5个钢珠的移动方向都有两种可能:向左或者向右。这样钢珠运动的组合就有25次方,也就是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 {

    RIGHTLEFT;

    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厘米,那么所有钢珠离开凹轨的最短和最长时间是多少?

 *

 * @author Eric

 *

 */

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)) {

              crawl(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 crawl(Ball[] balls) {

       for (Ball ant : balls) {

           ant.move();

       }

    }

 

    /**

     * 5只钢珠,每只钢珠可以向左(朝0的方向走),也可以向右(朝27的方向走), 这样的话有25次方,也就是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 static void main(String[] args) {

       new BallMoveScene().proceed();

    }

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值