假定街道是棋盘型的,每格距离相等,车辆通过每格街道需要时间均为 timePerRoad;
街道的街口(交叉点)有交通灯,灯的周期T(=lights[row][col])各不相同;
车辆可直行、左转和右转,其中直行和左转需要等相应T时间的交通灯才可通行,右转无需等待。
现给出 n*m 个街口的交通灯周期,以及起止街口的坐标,计算车辆经过两个街口的最短时间。
其中:
1)起点和终点的交通灯不计入时间,且可以任意方向经过街口;
2)不可超出 n*m 个街口,不可跳跃,但边线也是道路(即 lights[0][0] -> lights[0][1] 是有效路径)。
入口函数定义:
* lights : n*m 个街口每个交通灯的周期,值范围[0,120],n和m的范围为[1,9]
* timePerRoad : 相邻两个街口之间街道的通过时间,范围为[0,600]
* rowStart : 起点的行号
* colStart : 起点的列号
* rowEnd : 终点的行号
* colEnd : 终点的列号
* return : lights[rowStart][colStart] 与 lights[rowEnd][colEnd] 两个街口之间的最短通行时间
int calcTime(int[][] lights,int timePerRoad,int rowStart,int colStart,int rowEnd,int colEnd)
(1)车辆可直行、左转和右转,其中直行和左转需要等相应T时间的交通灯才可通行,右转无需等待:
直行是对当前方向状态的继承,左右转已经包含了所有的可移动方向(上下左右),但要注意边界。
直行和左转需要等相应T时间的交通灯:虽然说是周期,但只是叠加T,简化了问题,并未动态计算总时间。
当前方向是绝对的!!!转向是相对的!!
(当位置在上/下边界时,当前方向为左则不可再往右/左,当前方向为右则不可以再往左/右;当位置为左/右边界时,当前方向为上则不可往左/右,当前方向为下则不可以再往右/左。)!
(2)计算车辆经过两个街口的最短时间:从起点到终点路上花的最短时间,不包括起点和终点的等灯时间。
联想过马路,我在(0,0)路口准备出发前往(0,1)需要等待(0,1)路口的红绿灯,加上我的行走用时,就是我这一小段距离的用时。
经过两个街口的最短时间,即路径上所有段路线所花时间(x个timePerRoad)+随方向状态而动的所有节点等待值。
定义一个动点类:横纵坐标:row col ,用时:spendtime ,面向:facedirection ,转向:movedirection。
①初始化起点,给它赋值四个面向(绝对位置),0上,1右,2下,3左(顺时针,与遍历顺序一致);
②动点当前值与移动方向叠加,对在边界内的动点进行计算;
③将计算完的动点存入根据用时从小到大排列的优先队列,投入递归继续计算;
④遍历到终点坐标返回当前时间(因为优先队列的特性,拿取的最顶端就是最小的)。
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//输入时间周期数组
System.out.println("请输入车辆通过每格街道需要的时间timePerRoad[0,600]:");
int timePerRoad = sc.nextInt();
if (timePerRoad>=0&&timePerRoad<=600){
System.out.println("时间timePerRoad:"+timePerRoad+",设置成功!");
}else {
System.out.println("非法输入!");
return;
}
//输入棋盘长宽
System.out.println("请输入街道的长n和宽m[1,9]:");
int n = sc.nextInt();
int m = sc.nextInt();
if (n>=1 && n<=9 && m>=1 && m<=9){
System.out.println("街道长n:"+n+",宽m:"+m+",设置成功!");
}else {
System.out.println("非法输入!");
return;
}
//输入交通灯周期数组
System.out.println("请输入n*m 个街口的交通灯周期T(=lights[row][col])[0,120]:");
int[][] lights = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
lights[i][j] = sc.nextInt();
if (lights[i][j]>=0&&lights[i][j]<=120){
System.out.println("位置["+i+"]["+j+"]处的交通灯时间T:"+lights[i][j]+",设置成功!");
}else {
System.out.println("非法输入!");
return;
}
}
}
System.out.println("交通灯周期设置成功:");
for (int[] row : lights) {
System.out.println(Arrays.toString(row));
}
//输入起止街口的坐标
System.out.println("请输入起点的行号rowStart:");
int rowStart = sc.nextInt();
System.out.println("请输入起点的列号colStart:");
int colStart = sc.nextInt();
System.out.println("请输入终点的行号rowEnd:");
int rowEnd = sc.nextInt();
System.out.println("请输入终点的列号colEnd:");
int colEnd = sc.nextInt();
//int time = calcTime(lights,timePerRoad,rowStart,colStart,rowEnd,colEnd);
System.out.println("车辆经过两个街口的最短时间为:"+calcTime(lights,timePerRoad,rowStart,colStart,rowEnd,colEnd));//从起点到终点的最短时间
}
public static int[][] DIRECTION = {
{0,1},//上up0
{1,0},//右right1
{0,-1},//下down2
{-1,0}//左left3
};
private static int calcTime(int[][] lights, int timePerRoad, int rowStart, int colStart, int rowEnd, int colEnd) {
//----------------------------------
int n = lights.length;
int m = lights[0].length;
//
PriorityQueue pqMoveSpot = new PriorityQueue<>(
Comparator.comparingInt(MoveSpot::getTimeSpend));
MoveSpot start = new MoveSpot(rowStart,colStart,0,-1, MoveSpot.Move.NoMoveDirection);
pqMoveSpot.add(start);
//当优先队列不为空时,当前只存了start点
MoveSpot startMoveSpot = pqMoveSpot.poll();
//赋值
int startx = startMoveSpot.position[0];//row
int starty = startMoveSpot.position[1];//col
int startTime = startMoveSpot.timeSpend;//时间
int startfaceDir = startMoveSpot.FaceDirection;//面向
MoveSpot.Move startmoveDir = startMoveSpot.direction;//转向
//起点初始化,无面向无转向,面向可为可上下左右
if (startfaceDir==-1&&startmoveDir== MoveSpot.Move.NoMoveDirection){
for (int i=0;i<4;i++){
//上
if (i==0){
startfaceDir = 0;//将当前的面向改为上
//刚出发不考虑转向,随便设置,转向是后期根据面向改变进行判断的,可不设置
startmoveDir = MoveSpot.Move.GoStraight;
pqMoveSpot.offer(new MoveSpot(rowStart,colStart,0,startfaceDir, startmoveDir));
}
//右
if (i==1){
startfaceDir = 1;//将当前的面向改为上
//刚出发不考虑转向,随便设置,转向是后期根据面向改变进行判断的,可不设置
startmoveDir = MoveSpot.Move.GoStraight;
pqMoveSpot.offer(new MoveSpot(rowStart,colStart,0,startfaceDir, startmoveDir));
}
//下
if (i==2){
startfaceDir = 2;//将当前的面向改为上
//刚出发不考虑转向,随便设置,转向是后期根据面向改变进行判断的,可不设置
startmoveDir = MoveSpot.Move.GoStraight;
pqMoveSpot.offer(new MoveSpot(rowStart,colStart,0,startfaceDir, startmoveDir));
}
//左
if (i==3){
startfaceDir = 3;//将当前的面向改为上
//刚出发不考虑转向,随便设置,转向是后期根据面向改变进行判断的,可不设置
startmoveDir = MoveSpot.Move.GoStraight;
pqMoveSpot.offer(new MoveSpot(rowStart,colStart,0,startfaceDir, startmoveDir));
}
}
}
/*
for (int i=0;i<4;i++){
System.out.println("看看初始化好没"+pqMoveSpot.poll());
}
*/
shortesPassTime=findMoveRoad(pqMoveSpot,rowEnd,colEnd,lights,timePerRoad);//=======================调用
/* if (!pqMoveSpot.isEmpty()){
/// shortesPassTime=pqMoveSpot.peek().getTimeSpend();
}*/
//时间=路线经过格子数量*tPR+经过格子的灯周期累计(右转=0/直左=T) 算路线?根据累积量来?
//起点终点时间不计算
return shortesPassTime;
}
private static int findMoveRoad(PriorityQueue pqMoveSpot,int rowEnd,int colEnd,int[][] lights,int timePerRoad) {
int n = lights.length;
int m = lights[0].length;
PriorityQueue newpqMoveSpot = new PriorityQueue<>(
Comparator.comparingInt(MoveSpot::getTimeSpend));
while (!pqMoveSpot.isEmpty()) {
//从队列中拿出放入当前动点
MoveSpot currentMoveSpot = pqMoveSpot.poll();
//赋值
int x = currentMoveSpot.position[0];//row
int y = currentMoveSpot.position[1];//col
int currentTime = currentMoveSpot.timeSpend;//时间
int currentfaceDir = currentMoveSpot.FaceDirection;//面向
MoveSpot.Move currentmoveDir = currentMoveSpot.direction;//转向
//当到了终点就返回时间
if (x == rowEnd && y == colEnd) {
return currentTime;
}
//遍历四个方向
for (int i = 0; i < 4; i++) {
x = currentMoveSpot.position[0];//row
y = currentMoveSpot.position[1];//col
currentTime = currentMoveSpot.timeSpend;//时间
currentfaceDir = currentMoveSpot.FaceDirection;//面向
currentmoveDir = currentMoveSpot.direction;//转向
//eg:i=0,取DIRECTION[0][0]与DIRECTION[0][1]即向上(x+0,y+1)
int newX = x + DIRECTION[i][0];
int newY = y + DIRECTION[i][1];
//在边界内
if (newX >= 0 && newX < n && newY >= 0 && newY < m) {
MoveSpot.Move movedirection = currentmoveDir;
if (currentfaceDir == i) {//面向一致
currentTime = currentMoveSpot.timeSpend;
movedirection = MoveSpot.Move.GoStraight;
currentTime = currentTime + lights[newX][newY] + timePerRoad;//直行时间为交通灯等待时间+行走时间
currentfaceDir = i;
} else {//面向不一致
if (Math.abs(currentfaceDir - i) == 2) {//若需要转两次
continue;
} else {
//01 12 23 30右转
if (i - currentfaceDir == 1 || (currentfaceDir == 3 && i == 0)) {
currentTime = currentMoveSpot.timeSpend;
movedirection = MoveSpot.Move.TurnRight;
currentTime = currentTime + timePerRoad;//右转时间为行走时间
currentfaceDir = i;
}
//03 10 21 32左转
else if (currentfaceDir - i == 1 || (currentfaceDir == 0 && i == 3)) {
currentTime = currentMoveSpot.timeSpend;
movedirection = MoveSpot.Move.TurnLeft;
currentTime = currentTime + lights[newX][newY] + timePerRoad;//左转时间为交通灯等待时间+行走时间
currentfaceDir = i;
}
}
}
//加入队列
MoveSpot newSpot = new MoveSpot(newX, newY, currentTime, currentfaceDir, movedirection);
newSpot.position[0] = newX;
newSpot.position[1] = newY;
newSpot.timeSpend = currentTime;
newSpot.direction = movedirection;
newSpot.FaceDirection = currentfaceDir;
newpqMoveSpot.offer(newSpot);
}//边界内判断
}//四方向循环
}
/*
for (int i = 0; i < 10; i++) {
System.out.println("newpq检查:"+newpqMoveSpot.poll());
}
*/
shorttime = findMoveRoad(newpqMoveSpot, rowEnd, colEnd, lights, timePerRoad);
return shorttime;
}
//定义一个动点类
public static class MoveSpot {
private int[] position = new int[2];//位置 {row,col}
private int timeSpend;//用时
private int FaceDirection;//面向
private Move direction;//转向
public class FaceDirection{
public static final int NULL = -1;
public static final int UP = 0;
public static final int DOWN = 1;
public static final int LEFT = 2;
public static final int RIGHT = 3;
}
//转向枚举
public enum Move {
NoMoveDirection,GoStraight,TurnLeft,TurnRight;
}
//构造函数
public MoveSpot(int row , int col , int timeSpend, int faceDirection,Move direction) {
this.position[0] = row;//位置行列
this.position[1] = col;
this.timeSpend = timeSpend;
this.FaceDirection = faceDirection;
this.direction = direction;
}
//方法
//位置
public int[] getPosition() {
return position;
}
public void setPosition(int row, int col) {
this.position[0] = row;
this.position[1] = col;
}
//时间
public int getTimeSpend() {
return timeSpend;
}
public void setTimeSpend(int timeSpend) {
this.timeSpend = timeSpend;
}
//面向
public int getFaceDirection() {
return FaceDirection;
}
public void setFaceDirection(int faceDirection) {
FaceDirection = faceDirection;
}
//转向
public Move getDirection() {
return direction;
}
public void setDirection(Move direction) {
this.direction = direction;
}
//输出
public String toString(){
return "汽车"+ "到达["+position[0]+","
+position[1]+"]处"
+",用时为"+timeSpend
+",当前面向为:"+FaceDirection
+",当前行动状态为"+direction+"。";
}
}
public static int shorttime = Integer.MAX_VALUE;
public static int shortesPassTime = Integer.MAX_VALUE;
请输入车辆通过每格街道需要的时间timePerRoad[0,600]:
2
时间timePerRoad:2,设置成功!
请输入街道的长n和宽m[1,9]:
3
2
街道长n:3,宽m:2,设置成功!
请输入n*m 个街口的交通灯周期T(=lights[row][col])[0,120]:
1 2 3 4 5 6
位置[0][0]处的交通灯时间T:1,设置成功!
位置[0][1]处的交通灯时间T:2,设置成功!
位置[1][0]处的交通灯时间T:3,设置成功!
位置[1][1]处的交通灯时间T:4,设置成功!
位置[2][0]处的交通灯时间T:5,设置成功!
位置[2][1]处的交通灯时间T:6,设置成功!
交通灯周期设置成功:
[1, 2]
[3, 4]
[5, 6]
请输入起点的行号rowStart:
0
请输入起点的列号colStart:
0
请输入终点的行号rowEnd:
2
请输入终点的列号colEnd:
1
汽车到达[0,0]处,用时为0,当前面向为:-1,当前行动状态为NoMoveDirection。
0 0 0 -1 NoMoveDirection
面向为:0,转向为:GoStraight
面向为:1,转向为:GoStraight
面向为:2,转向为:GoStraight
面向为:3,转向为:GoStraight
取值进入循环了:0 0 0 0 GoStraight
0 ===1
我是在边界内的下一个可移动点的坐标:[0,1],当前的转向为:GoStraight
当前用时为:0,当前面向为:0,此时的目标面向i为0。为了从当前位置[0,0]到下个位置[0,1]需要直走。
从当前位置[0,0]到下个位置[0,1],需要等待2,加上行走用时:2,直走后面向为0,所用时间为:4
入列传值检查:[0,1],4 GoStraight 0
newSpot传值检验:到达[0,1]后,当前动点的状态:用时:4,转向:GoStraight,面向:0
2 2147483647
1 ===0
我是在边界内的下一个可移动点的坐标:[1,0],当前的转向为:GoStraight
当前用时为:0,当前面向为:0,此时的目标面向i为1。为了从当前位置[0,0]到下个位置[1,0]需要右转。
从当前位置[0,0]到下个位置[1,0],无需等待,加上行走用时:2,右转后面向为1,所用时间为:2
入列传值检查:[1,0],2 TurnRight 1
newSpot传值检验:到达[1,0]后,当前动点的状态:用时:2,转向:TurnRight,面向:1
2 2147483647
0 ===-1
-1 ===0
取值进入循环了:0 0 0 3 GoStraight
0 ===1
我是在边界内的下一个可移动点的坐标:[0,1],当前的转向为:GoStraight
当前用时为:0,当前面向为:3,此时的目标面向i为0。为了从当前位置[0,0]到下个位置[0,1]需要右转。
从当前位置[0,0]到下个位置[0,1],无需等待,加上行走用时:2,右转后面向为0,所用时间为:2
入列传值检查:[0,1],2 TurnRight 0
newSpot传值检验:到达[0,1]后,当前动点的状态:用时:2,转向:TurnRight,面向:0
2 2147483647
1 ===0
我是在边界内的下一个可移动点的坐标:[1,0],当前的转向为:GoStraight
只能转一次,此次不记录
0 ===-1
-1 ===0
取值进入循环了:0 0 0 2 GoStraight
0 ===1
我是在边界内的下一个可移动点的坐标:[0,1],当前的转向为:GoStraight
只能转一次,此次不记录
1 ===0
我是在边界内的下一个可移动点的坐标:[1,0],当前的转向为:GoStraight
当前用时为:0,当前面向为:2,此时的目标面向i为1。为了从当前位置[0,0]到下个位置[1,0]需要左转。
从当前位置[0,0]到下个位置[1,0],需要等待3,加上行走用时:2,左转后面向为1,所用时间为:5
入列传值检查:[1,0],5 TurnLeft 1
newSpot传值检验:到达[1,0]后,当前动点的状态:用时:5,转向:TurnLeft,面向:1
2 2147483647
0 ===-1
-1 ===0
取值进入循环了:0 0 0 1 GoStraight
0 ===1
我是在边界内的下一个可移动点的坐标:[0,1],当前的转向为:GoStraight
当前用时为:0,当前面向为:1,此时的目标面向i为0。为了从当前位置[0,0]到下个位置[0,1]需要左转。
从当前位置[0,0]到下个位置[0,1],需要等待2,加上行走用时:2,左转后面向为0,所用时间为:4
入列传值检查:[0,1],4 TurnLeft 0
newSpot传值检验:到达[0,1]后,当前动点的状态:用时:4,转向:TurnLeft,面向:0
2 2147483647
1 ===0
我是在边界内的下一个可移动点的坐标:[1,0],当前的转向为:GoStraight
当前用时为:0,当前面向为:1,此时的目标面向i为1。为了从当前位置[0,0]到下个位置[1,0]需要直走。
从当前位置[0,0]到下个位置[1,0],需要等待3,加上行走用时:2,直走后面向为1,所用时间为:5
入列传值检查:[1,0],5 GoStraight 1
newSpot传值检验:到达[1,0]后,当前动点的状态:用时:5,转向:GoStraight,面向:1
2 2147483647
0 ===-1
-1 ===0
取值进入循环了:1 0 2 1 TurnRight
1 ===1
我是在边界内的下一个可移动点的坐标:[1,1],当前的转向为:TurnRight
当前用时为:2,当前面向为:1,此时的目标面向i为0。为了从当前位置[1,0]到下个位置[1,1]需要左转。
从当前位置[1,0]到下个位置[1,1],需要等待4,加上行走用时:2,左转后面向为0,所用时间为:8
入列传值检查:[1,1],8 TurnLeft 0
newSpot传值检验:到达[1,1]后,当前动点的状态:用时:8,转向:TurnLeft,面向:0
2 2147483647
2 ===0
我是在边界内的下一个可移动点的坐标:[2,0],当前的转向为:TurnRight
当前用时为:2,当前面向为:1,此时的目标面向i为1。为了从当前位置[1,0]到下个位置[2,0]需要直走。
从当前位置[1,0]到下个位置[2,0],需要等待5,加上行走用时:2,直走后面向为1,所用时间为:9
入列传值检查:[2,0],9 GoStraight 1
newSpot传值检验:到达[2,0]后,当前动点的状态:用时:9,转向:GoStraight,面向:1
2 2147483647
1 ===-1
0 ===0
我是在边界内的下一个可移动点的坐标:[0,0],当前的转向为:TurnRight
只能转一次,此次不记录
取值进入循环了:0 1 2 0 TurnRight
0 ===2
1 ===1
我是在边界内的下一个可移动点的坐标:[1,1],当前的转向为:TurnRight
当前用时为:2,当前面向为:0,此时的目标面向i为1。为了从当前位置[0,1]到下个位置[1,1]需要右转。
从当前位置[0,1]到下个位置[1,1],无需等待,加上行走用时:2,右转后面向为1,所用时间为:4
入列传值检查:[1,1],4 TurnRight 1
newSpot传值检验:到达[1,1]后,当前动点的状态:用时:4,转向:TurnRight,面向:1
2 2147483647
0 ===0
我是在边界内的下一个可移动点的坐标:[0,0],当前的转向为:TurnRight
只能转一次,此次不记录
-1 ===1
取值进入循环了:0 1 4 0 TurnLeft
0 ===2
1 ===1
我是在边界内的下一个可移动点的坐标:[1,1],当前的转向为:TurnLeft
当前用时为:4,当前面向为:0,此时的目标面向i为1。为了从当前位置[0,1]到下个位置[1,1]需要右转。
从当前位置[0,1]到下个位置[1,1],无需等待,加上行走用时:2,右转后面向为1,所用时间为:6
入列传值检查:[1,1],6 TurnRight 1
newSpot传值检验:到达[1,1]后,当前动点的状态:用时:6,转向:TurnRight,面向:1
2 2147483647
0 ===0
我是在边界内的下一个可移动点的坐标:[0,0],当前的转向为:TurnLeft
只能转一次,此次不记录
-1 ===1
取值进入循环了:0 1 4 0 GoStraight
0 ===2
1 ===1
我是在边界内的下一个可移动点的坐标:[1,1],当前的转向为:GoStraight
当前用时为:4,当前面向为:0,此时的目标面向i为1。为了从当前位置[0,1]到下个位置[1,1]需要右转。
从当前位置[0,1]到下个位置[1,1],无需等待,加上行走用时:2,右转后面向为1,所用时间为:6
入列传值检查:[1,1],6 TurnRight 1
newSpot传值检验:到达[1,1]后,当前动点的状态:用时:6,转向:TurnRight,面向:1
2 2147483647
0 ===0
我是在边界内的下一个可移动点的坐标:[0,0],当前的转向为:GoStraight
只能转一次,此次不记录
-1 ===1
取值进入循环了:1 0 5 1 GoStraight
1 ===1
我是在边界内的下一个可移动点的坐标:[1,1],当前的转向为:GoStraight
当前用时为:5,当前面向为:1,此时的目标面向i为0。为了从当前位置[1,0]到下个位置[1,1]需要左转。
从当前位置[1,0]到下个位置[1,1],需要等待4,加上行走用时:2,左转后面向为0,所用时间为:11
入列传值检查:[1,1],11 TurnLeft 0
newSpot传值检验:到达[1,1]后,当前动点的状态:用时:11,转向:TurnLeft,面向:0
2 2147483647
2 ===0
我是在边界内的下一个可移动点的坐标:[2,0],当前的转向为:GoStraight
当前用时为:5,当前面向为:1,此时的目标面向i为1。为了从当前位置[1,0]到下个位置[2,0]需要直走。
从当前位置[1,0]到下个位置[2,0],需要等待5,加上行走用时:2,直走后面向为1,所用时间为:12
入列传值检查:[2,0],12 GoStraight 1
newSpot传值检验:到达[2,0]后,当前动点的状态:用时:12,转向:GoStraight,面向:1
2 2147483647
1 ===-1
0 ===0
我是在边界内的下一个可移动点的坐标:[0,0],当前的转向为:GoStraight
只能转一次,此次不记录
取值进入循环了:1 0 5 1 TurnLeft
1 ===1
我是在边界内的下一个可移动点的坐标:[1,1],当前的转向为:TurnLeft
当前用时为:5,当前面向为:1,此时的目标面向i为0。为了从当前位置[1,0]到下个位置[1,1]需要左转。
从当前位置[1,0]到下个位置[1,1],需要等待4,加上行走用时:2,左转后面向为0,所用时间为:11
入列传值检查:[1,1],11 TurnLeft 0
newSpot传值检验:到达[1,1]后,当前动点的状态:用时:11,转向:TurnLeft,面向:0
2 2147483647
2 ===0
我是在边界内的下一个可移动点的坐标:[2,0],当前的转向为:TurnLeft
当前用时为:5,当前面向为:1,此时的目标面向i为1。为了从当前位置[1,0]到下个位置[2,0]需要直走。
从当前位置[1,0]到下个位置[2,0],需要等待5,加上行走用时:2,直走后面向为1,所用时间为:12
入列传值检查:[2,0],12 GoStraight 1
newSpot传值检验:到达[2,0]后,当前动点的状态:用时:12,转向:GoStraight,面向:1
2 2147483647
1 ===-1
0 ===0
我是在边界内的下一个可移动点的坐标:[0,0],当前的转向为:TurnLeft
只能转一次,此次不记录
取值进入循环了:1 1 4 1 TurnRight
1 ===2
2 ===1
我是在边界内的下一个可移动点的坐标:[2,1],当前的转向为:TurnRight
当前用时为:4,当前面向为:1,此时的目标面向i为1。为了从当前位置[1,1]到下个位置[2,1]需要直走。
从当前位置[1,1]到下个位置[2,1],需要等待6,加上行走用时:2,直走后面向为1,所用时间为:12
入列传值检查:[2,1],12 GoStraight 1
newSpot传值检验:到达[2,1]后,当前动点的状态:用时:12,转向:GoStraight,面向:1
2 2147483647
1 ===0
我是在边界内的下一个可移动点的坐标:[1,0],当前的转向为:TurnRight
当前用时为:4,当前面向为:1,此时的目标面向i为2。为了从当前位置[1,1]到下个位置[1,0]需要右转。
从当前位置[1,1]到下个位置[1,0],无需等待,加上行走用时:2,右转后面向为2,所用时间为:6
入列传值检查:[1,0],6 TurnRight 2
newSpot传值检验:到达[1,0]后,当前动点的状态:用时:6,转向:TurnRight,面向:2
2 2147483647
0 ===1
我是在边界内的下一个可移动点的坐标:[0,1],当前的转向为:TurnRight
只能转一次,此次不记录
取值进入循环了:1 1 6 1 TurnRight
1 ===2
2 ===1
我是在边界内的下一个可移动点的坐标:[2,1],当前的转向为:TurnRight
当前用时为:6,当前面向为:1,此时的目标面向i为1。为了从当前位置[1,1]到下个位置[2,1]需要直走。
从当前位置[1,1]到下个位置[2,1],需要等待6,加上行走用时:2,直走后面向为1,所用时间为:14
入列传值检查:[2,1],14 GoStraight 1
newSpot传值检验:到达[2,1]后,当前动点的状态:用时:14,转向:GoStraight,面向:1
2 2147483647
1 ===0
我是在边界内的下一个可移动点的坐标:[1,0],当前的转向为:TurnRight
当前用时为:6,当前面向为:1,此时的目标面向i为2。为了从当前位置[1,1]到下个位置[1,0]需要右转。
从当前位置[1,1]到下个位置[1,0],无需等待,加上行走用时:2,右转后面向为2,所用时间为:8
入列传值检查:[1,0],8 TurnRight 2
newSpot传值检验:到达[1,0]后,当前动点的状态:用时:8,转向:TurnRight,面向:2
2 2147483647
0 ===1
我是在边界内的下一个可移动点的坐标:[0,1],当前的转向为:TurnRight
只能转一次,此次不记录
取值进入循环了:1 1 6 1 TurnRight
1 ===2
2 ===1
我是在边界内的下一个可移动点的坐标:[2,1],当前的转向为:TurnRight
当前用时为:6,当前面向为:1,此时的目标面向i为1。为了从当前位置[1,1]到下个位置[2,1]需要直走。
从当前位置[1,1]到下个位置[2,1],需要等待6,加上行走用时:2,直走后面向为1,所用时间为:14
入列传值检查:[2,1],14 GoStraight 1
newSpot传值检验:到达[2,1]后,当前动点的状态:用时:14,转向:GoStraight,面向:1
2 2147483647
1 ===0
我是在边界内的下一个可移动点的坐标:[1,0],当前的转向为:TurnRight
当前用时为:6,当前面向为:1,此时的目标面向i为2。为了从当前位置[1,1]到下个位置[1,0]需要右转。
从当前位置[1,1]到下个位置[1,0],无需等待,加上行走用时:2,右转后面向为2,所用时间为:8
入列传值检查:[1,0],8 TurnRight 2
newSpot传值检验:到达[1,0]后,当前动点的状态:用时:8,转向:TurnRight,面向:2
2 2147483647
0 ===1
我是在边界内的下一个可移动点的坐标:[0,1],当前的转向为:TurnRight
只能转一次,此次不记录
取值进入循环了:1 1 8 0 TurnLeft
1 ===2
2 ===1
我是在边界内的下一个可移动点的坐标:[2,1],当前的转向为:TurnLeft
当前用时为:8,当前面向为:0,此时的目标面向i为1。为了从当前位置[1,1]到下个位置[2,1]需要右转。
从当前位置[1,1]到下个位置[2,1],无需等待,加上行走用时:2,右转后面向为1,所用时间为:10
入列传值检查:[2,1],10 TurnRight 1
newSpot传值检验:到达[2,1]后,当前动点的状态:用时:10,转向:TurnRight,面向:1
2 2147483647
1 ===0
我是在边界内的下一个可移动点的坐标:[1,0],当前的转向为:TurnLeft
只能转一次,此次不记录
0 ===1
我是在边界内的下一个可移动点的坐标:[0,1],当前的转向为:TurnLeft
当前用时为:8,当前面向为:0,此时的目标面向i为3。为了从当前位置[1,1]到下个位置[0,1]需要左转。
从当前位置[1,1]到下个位置[0,1],需要等待2,加上行走用时:2,左转后面向为3,所用时间为:12
入列传值检查:[0,1],12 TurnLeft 3
newSpot传值检验:到达[0,1]后,当前动点的状态:用时:12,转向:TurnLeft,面向:3
2 2147483647
取值进入循环了:2 0 9 1 GoStraight
2 ===1
我是在边界内的下一个可移动点的坐标:[2,1],当前的转向为:GoStraight
当前用时为:9,当前面向为:1,此时的目标面向i为0。为了从当前位置[2,0]到下个位置[2,1]需要左转。
从当前位置[2,0]到下个位置[2,1],需要等待6,加上行走用时:2,左转后面向为0,所用时间为:17
入列传值检查:[2,1],17 TurnLeft 0
newSpot传值检验:到达[2,1]后,当前动点的状态:用时:17,转向:TurnLeft,面向:0
2 2147483647
3 ===0
2 ===-1
1 ===0
我是在边界内的下一个可移动点的坐标:[1,0],当前的转向为:GoStraight
只能转一次,此次不记录
取值进入循环了:1 1 11 0 TurnLeft
1 ===2
2 ===1
我是在边界内的下一个可移动点的坐标:[2,1],当前的转向为:TurnLeft
当前用时为:11,当前面向为:0,此时的目标面向i为1。为了从当前位置[1,1]到下个位置[2,1]需要右转。
从当前位置[1,1]到下个位置[2,1],无需等待,加上行走用时:2,右转后面向为1,所用时间为:13
入列传值检查:[2,1],13 TurnRight 1
newSpot传值检验:到达[2,1]后,当前动点的状态:用时:13,转向:TurnRight,面向:1
2 2147483647
1 ===0
我是在边界内的下一个可移动点的坐标:[1,0],当前的转向为:TurnLeft
只能转一次,此次不记录
0 ===1
我是在边界内的下一个可移动点的坐标:[0,1],当前的转向为:TurnLeft
当前用时为:11,当前面向为:0,此时的目标面向i为3。为了从当前位置[1,1]到下个位置[0,1]需要左转。
从当前位置[1,1]到下个位置[0,1],需要等待2,加上行走用时:2,左转后面向为3,所用时间为:15
入列传值检查:[0,1],15 TurnLeft 3
newSpot传值检验:到达[0,1]后,当前动点的状态:用时:15,转向:TurnLeft,面向:3
2 2147483647
取值进入循环了:1 1 11 0 TurnLeft
1 ===2
2 ===1
我是在边界内的下一个可移动点的坐标:[2,1],当前的转向为:TurnLeft
当前用时为:11,当前面向为:0,此时的目标面向i为1。为了从当前位置[1,1]到下个位置[2,1]需要右转。
从当前位置[1,1]到下个位置[2,1],无需等待,加上行走用时:2,右转后面向为1,所用时间为:13
入列传值检查:[2,1],13 TurnRight 1
newSpot传值检验:到达[2,1]后,当前动点的状态:用时:13,转向:TurnRight,面向:1
2 2147483647
1 ===0
我是在边界内的下一个可移动点的坐标:[1,0],当前的转向为:TurnLeft
只能转一次,此次不记录
0 ===1
我是在边界内的下一个可移动点的坐标:[0,1],当前的转向为:TurnLeft
当前用时为:11,当前面向为:0,此时的目标面向i为3。为了从当前位置[1,1]到下个位置[0,1]需要左转。
从当前位置[1,1]到下个位置[0,1],需要等待2,加上行走用时:2,左转后面向为3,所用时间为:15
入列传值检查:[0,1],15 TurnLeft 3
newSpot传值检验:到达[0,1]后,当前动点的状态:用时:15,转向:TurnLeft,面向:3
2 2147483647
取值进入循环了:2 0 12 1 GoStraight
2 ===1
我是在边界内的下一个可移动点的坐标:[2,1],当前的转向为:GoStraight
当前用时为:12,当前面向为:1,此时的目标面向i为0。为了从当前位置[2,0]到下个位置[2,1]需要左转。
从当前位置[2,0]到下个位置[2,1],需要等待6,加上行走用时:2,左转后面向为0,所用时间为:20
入列传值检查:[2,1],20 TurnLeft 0
newSpot传值检验:到达[2,1]后,当前动点的状态:用时:20,转向:TurnLeft,面向:0
2 2147483647
3 ===0
2 ===-1
1 ===0
我是在边界内的下一个可移动点的坐标:[1,0],当前的转向为:GoStraight
只能转一次,此次不记录
取值进入循环了:2 0 12 1 GoStraight
2 ===1
我是在边界内的下一个可移动点的坐标:[2,1],当前的转向为:GoStraight
当前用时为:12,当前面向为:1,此时的目标面向i为0。为了从当前位置[2,0]到下个位置[2,1]需要左转。
从当前位置[2,0]到下个位置[2,1],需要等待6,加上行走用时:2,左转后面向为0,所用时间为:20
入列传值检查:[2,1],20 TurnLeft 0
newSpot传值检验:到达[2,1]后,当前动点的状态:用时:20,转向:TurnLeft,面向:0
2 2147483647
3 ===0
2 ===-1
1 ===0
我是在边界内的下一个可移动点的坐标:[1,0],当前的转向为:GoStraight
只能转一次,此次不记录
取值进入循环了:1 0 6 2 TurnRight
1 ===1
我是在边界内的下一个可移动点的坐标:[1,1],当前的转向为:TurnRight
只能转一次,此次不记录
2 ===0
我是在边界内的下一个可移动点的坐标:[2,0],当前的转向为:TurnRight
当前用时为:6,当前面向为:2,此时的目标面向i为1。为了从当前位置[1,0]到下个位置[2,0]需要左转。
从当前位置[1,0]到下个位置[2,0],需要等待5,加上行走用时:2,左转后面向为1,所用时间为:13
入列传值检查:[2,0],13 TurnLeft 1
newSpot传值检验:到达[2,0]后,当前动点的状态:用时:13,转向:TurnLeft,面向:1
2 2147483647
1 ===-1
0 ===0
我是在边界内的下一个可移动点的坐标:[0,0],当前的转向为:TurnRight
当前用时为:6,当前面向为:2,此时的目标面向i为3。为了从当前位置[1,0]到下个位置[0,0]需要右转。
从当前位置[1,0]到下个位置[0,0],无需等待,加上行走用时:2,右转后面向为3,所用时间为:8
入列传值检查:[0,0],8 TurnRight 3
newSpot传值检验:到达[0,0]后,当前动点的状态:用时:8,转向:TurnRight,面向:3
2 2147483647
取值进入循环了:1 0 8 2 TurnRight
1 ===1
我是在边界内的下一个可移动点的坐标:[1,1],当前的转向为:TurnRight
只能转一次,此次不记录
2 ===0
我是在边界内的下一个可移动点的坐标:[2,0],当前的转向为:TurnRight
当前用时为:8,当前面向为:2,此时的目标面向i为1。为了从当前位置[1,0]到下个位置[2,0]需要左转。
从当前位置[1,0]到下个位置[2,0],需要等待5,加上行走用时:2,左转后面向为1,所用时间为:15
入列传值检查:[2,0],15 TurnLeft 1
newSpot传值检验:到达[2,0]后,当前动点的状态:用时:15,转向:TurnLeft,面向:1
2 2147483647
1 ===-1
0 ===0
我是在边界内的下一个可移动点的坐标:[0,0],当前的转向为:TurnRight
当前用时为:8,当前面向为:2,此时的目标面向i为3。为了从当前位置[1,0]到下个位置[0,0]需要右转。
从当前位置[1,0]到下个位置[0,0],无需等待,加上行走用时:2,右转后面向为3,所用时间为:10
入列传值检查:[0,0],10 TurnRight 3
newSpot传值检验:到达[0,0]后,当前动点的状态:用时:10,转向:TurnRight,面向:3
2 2147483647
取值进入循环了:1 0 8 2 TurnRight
1 ===1
我是在边界内的下一个可移动点的坐标:[1,1],当前的转向为:TurnRight
只能转一次,此次不记录
2 ===0
我是在边界内的下一个可移动点的坐标:[2,0],当前的转向为:TurnRight
当前用时为:8,当前面向为:2,此时的目标面向i为1。为了从当前位置[1,0]到下个位置[2,0]需要左转。
从当前位置[1,0]到下个位置[2,0],需要等待5,加上行走用时:2,左转后面向为1,所用时间为:15
入列传值检查:[2,0],15 TurnLeft 1
newSpot传值检验:到达[2,0]后,当前动点的状态:用时:15,转向:TurnLeft,面向:1
2 2147483647
1 ===-1
0 ===0
我是在边界内的下一个可移动点的坐标:[0,0],当前的转向为:TurnRight
当前用时为:8,当前面向为:2,此时的目标面向i为3。为了从当前位置[1,0]到下个位置[0,0]需要右转。
从当前位置[1,0]到下个位置[0,0],无需等待,加上行走用时:2,右转后面向为3,所用时间为:10
入列传值检查:[0,0],10 TurnRight 3
newSpot传值检验:到达[0,0]后,当前动点的状态:用时:10,转向:TurnRight,面向:3
2 2147483647
取值进入循环了:2 1 10 1 TurnRight
1 10
3 10
3 10
3 10
最短是shortesPassTime 10
车辆经过两个街口的最短时间为:10
进程已结束,退出代码为 0
import java.util.Arrays;
import java.util.Comparator;
import java.util.PriorityQueue;
import java.util.Scanner;
public class test22 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
//输入时间周期数组
System.out.println("请输入车辆通过每格街道需要的时间timePerRoad[0,600]:");
int timePerRoad = sc.nextInt();
if (timePerRoad>=0&&timePerRoad<=600){
System.out.println("时间timePerRoad:"+timePerRoad+",设置成功!");
}else {
System.out.println("非法输入!");
return;
}
//输入棋盘长宽
System.out.println("请输入街道的长n和宽m[1,9]:");
int n = sc.nextInt();
int m = sc.nextInt();
if (n>=1 && n<=9 && m>=1 && m<=9){
System.out.println("街道长n:"+n+",宽m:"+m+",设置成功!");
}else {
System.out.println("非法输入!");
return;
}
//输入交通灯周期数组
System.out.println("请输入n*m 个街口的交通灯周期T(=lights[row][col])[0,120]:");
int[][] lights = new int[n][m];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
lights[i][j] = sc.nextInt();
if (lights[i][j]>=0&&lights[i][j]<=120){
System.out.println("位置["+i+"]["+j+"]处的交通灯时间T:"+lights[i][j]+",设置成功!");
}else {
System.out.println("非法输入!");
return;
}
}
}
System.out.println("交通灯周期设置成功:");
for (int[] row : lights) {
System.out.println(Arrays.toString(row));
}
//输入起止街口的坐标
System.out.println("请输入起点的行号rowStart:");
int rowStart = sc.nextInt();
System.out.println("请输入起点的列号colStart:");
int colStart = sc.nextInt();
System.out.println("请输入终点的行号rowEnd:");
int rowEnd = sc.nextInt();
System.out.println("请输入终点的列号colEnd:");
int colEnd = sc.nextInt();
//int time = calcTime(lights,timePerRoad,rowStart,colStart,rowEnd,colEnd);
System.out.println("车辆经过两个街口的最短时间为:"+calcTime(lights,timePerRoad,rowStart,colStart,rowEnd,colEnd));//从起点到终点的最短时间
}
public static int[][] DIRECTION = {
{0,1},//上up0
{1,0},//右right1
{0,-1},//下down2
{-1,0}//左left3
};
//注意边界!!!
public static int shortesPassTime = Integer.MAX_VALUE;
private static int calcTime(int[][] lights, int timePerRoad, int rowStart, int colStart, int rowEnd, int colEnd) {
//----------------------------------
int n = lights.length;
int m = lights[0].length;
//
PriorityQueue pqMoveSpot = new PriorityQueue<>(
Comparator.comparingInt(MoveSpot::getTimeSpend));
MoveSpot start = new MoveSpot(rowStart,colStart,0,-1, MoveSpot.Move.NoMoveDirection);
pqMoveSpot.add(start);
//打印检查-------------
for (MoveSpot move : pqMoveSpot) {
System.out.println(move);
}
//--------------------
//当优先队列不为空时,当前只存了start点
MoveSpot startMoveSpot = pqMoveSpot.poll();
//赋值
int startx = startMoveSpot.position[0];//row
int starty = startMoveSpot.position[1];//col
int startTime = startMoveSpot.timeSpend;//时间
int startfaceDir = startMoveSpot.FaceDirection;//面向
MoveSpot.Move startmoveDir = startMoveSpot.direction;//转向
//打印检验
System.out.println(startx + " " + starty + " " + startTime+" "+startfaceDir+" "+startmoveDir);
//起点初始化,无面向无转向,面向可为可上下左右
if (startfaceDir==-1&&startmoveDir== MoveSpot.Move.NoMoveDirection){
for (int i=0;i<4;i++){
//上
if (i==0){
startfaceDir = 0;//将当前的面向改为上
//刚出发不考虑转向,随便设置,转向是后期根据面向改变进行判断的,可不设置
startmoveDir = MoveSpot.Move.GoStraight;
System.out.println("面向为:"+startfaceDir+",转向为:"+startmoveDir);
pqMoveSpot.offer(new MoveSpot(rowStart,colStart,0,startfaceDir, startmoveDir));
}
//右
if (i==1){
startfaceDir = 1;//将当前的面向改为上
//刚出发不考虑转向,随便设置,转向是后期根据面向改变进行判断的,可不设置
startmoveDir = MoveSpot.Move.GoStraight;
System.out.println("面向为:"+startfaceDir+",转向为:"+startmoveDir);
pqMoveSpot.offer(new MoveSpot(rowStart,colStart,0,startfaceDir, startmoveDir));
}
//下
if (i==2){
startfaceDir = 2;//将当前的面向改为上
//刚出发不考虑转向,随便设置,转向是后期根据面向改变进行判断的,可不设置
startmoveDir = MoveSpot.Move.GoStraight;
System.out.println("面向为:"+startfaceDir+",转向为:"+startmoveDir);
pqMoveSpot.offer(new MoveSpot(rowStart,colStart,0,startfaceDir, startmoveDir));
}
//左
if (i==3){
startfaceDir = 3;//将当前的面向改为上
//刚出发不考虑转向,随便设置,转向是后期根据面向改变进行判断的,可不设置
startmoveDir = MoveSpot.Move.GoStraight;
System.out.println("面向为:"+startfaceDir+",转向为:"+startmoveDir);
pqMoveSpot.offer(new MoveSpot(rowStart,colStart,0,startfaceDir, startmoveDir));
}
}
}
/*
for (int i=0;i<4;i++){
System.out.println("看看初始化好没"+pqMoveSpot.poll());
}
*/
shortesPassTime=findMoveRoad(pqMoveSpot,rowEnd,colEnd,lights,timePerRoad);//=======================调用
System.out.println("最短是shortesPassTime "+shortesPassTime);
/* if (!pqMoveSpot.isEmpty()){
/// shortesPassTime=pqMoveSpot.peek().getTimeSpend();
}*/
//时间=路线经过格子数量*tPR+经过格子的灯周期累计(右转=0/直左=T) 算路线?根据累积量来?
//起点终点时间不计算
return shortesPassTime;
}
public static int shorttime = Integer.MAX_VALUE;;
private static int findMoveRoad(PriorityQueue pqMoveSpot,int rowEnd,int colEnd,int[][] lights,int timePerRoad) {
int n = lights.length;
int m = lights[0].length;
PriorityQueue newpqMoveSpot = new PriorityQueue<>(
Comparator.comparingInt(MoveSpot::getTimeSpend));
while (!pqMoveSpot.isEmpty()) {
//从队列中拿出放入当前动点
MoveSpot currentMoveSpot = pqMoveSpot.poll();
//赋值
int x = currentMoveSpot.position[0];//row
int y = currentMoveSpot.position[1];//col
int currentTime = currentMoveSpot.timeSpend;//时间
int currentfaceDir = currentMoveSpot.FaceDirection;//面向
MoveSpot.Move currentmoveDir = currentMoveSpot.direction;//转向
//打印检验
System.out.println("\n取值进入循环了:" + x + " " + y + " " + currentTime + " " + currentfaceDir + " " + currentmoveDir);
//当到了终点就返回时间
if (x == rowEnd && y == colEnd) {
System.out.println("1 "+currentTime);
return currentTime;
}
//遍历四个方向
for (int i = 0; i < 4; i++) {
x = currentMoveSpot.position[0];//row
y = currentMoveSpot.position[1];//col
currentTime = currentMoveSpot.timeSpend;//时间
currentfaceDir = currentMoveSpot.FaceDirection;//面向
currentmoveDir = currentMoveSpot.direction;//转向
//eg:i=0,取DIRECTION[0][0]与DIRECTION[0][1]即向上(x+0,y+1)
int newX = x + DIRECTION[i][0];
int newY = y + DIRECTION[i][1];
System.out.println(newX + " ===" + newY);
//在边界内
if (newX >= 0 && newX < n && newY >= 0 && newY < m) {
MoveSpot.Move movedirection = currentmoveDir;
System.out.println("我是在边界内的下一个可移动点的坐标:[" + newX + "," + newY + "],当前的转向为:" + movedirection);
if (currentfaceDir == i) {//面向一致
currentTime = currentMoveSpot.timeSpend;
System.out.println("当前用时为:" + currentTime + ",当前面向为:" + currentfaceDir + ",此时的目标面向i为" + i + "。为了从当前位置[" + x + "," + y + "]到下个位置[" + newX + "," + newY + "]需要直走。");
movedirection = MoveSpot.Move.GoStraight;
currentTime = currentTime + lights[newX][newY] + timePerRoad;//直行时间为交通灯等待时间+行走时间
currentfaceDir = i;
System.out.println("从当前位置[" + x + "," + y + "]到下个位置[" + newX + "," + newY + "],需要等待" + lights[newX][newY] + ",加上行走用时:" + timePerRoad + ",直走后面向为" + currentfaceDir + ",所用时间为:" + currentTime);
} else {//面向不一致
if (Math.abs(currentfaceDir - i) == 2) {//若需要转两次
System.out.println("只能转一次,此次不记录");
continue;
} else {
//01 12 23 30右转
if (i - currentfaceDir == 1 || (currentfaceDir == 3 && i == 0)) {
currentTime = currentMoveSpot.timeSpend;
System.out.println("当前用时为:" + currentTime + ",当前面向为:" + currentfaceDir + ",此时的目标面向i为" + i + "。为了从当前位置[" + x + "," + y + "]到下个位置[" + newX + "," + newY + "]需要右转。");
movedirection = MoveSpot.Move.TurnRight;
currentTime = currentTime + timePerRoad;//右转时间为行走时间
currentfaceDir = i;
System.out.println("从当前位置[" + x + "," + y + "]到下个位置[" + newX + "," + newY + "],无需等待,加上行走用时:" + timePerRoad + ",右转后面向为" + currentfaceDir + ",所用时间为:" + currentTime);
}
//03 10 21 32左转
else if (currentfaceDir - i == 1 || (currentfaceDir == 0 && i == 3)) {
currentTime = currentMoveSpot.timeSpend;
System.out.println("当前用时为:" + currentTime + ",当前面向为:" + currentfaceDir + ",此时的目标面向i为" + i + "。为了从当前位置[" + x + "," + y + "]到下个位置[" + newX + "," + newY + "]需要左转。");
movedirection = MoveSpot.Move.TurnLeft;
currentTime = currentTime + lights[newX][newY] + timePerRoad;//左转时间为交通灯等待时间+行走时间
currentfaceDir = i;
System.out.println("从当前位置[" + x + "," + y + "]到下个位置[" + newX + "," + newY + "],需要等待" + lights[newX][newY] + ",加上行走用时:" + timePerRoad + ",左转后面向为" + currentfaceDir + ",所用时间为:" + currentTime);
}
}
}
//加入队列
System.out.println("入列传值检查:[" + newX + "," + newY + "]," + currentTime + " " + movedirection + " " + currentfaceDir);
MoveSpot newSpot = new MoveSpot(newX, newY, currentTime, currentfaceDir, movedirection);
newSpot.position[0] = newX;
newSpot.position[1] = newY;
newSpot.timeSpend = currentTime;
newSpot.direction = movedirection;
newSpot.FaceDirection = currentfaceDir;
newpqMoveSpot.offer(newSpot);
System.out.println("newSpot传值检验:到达[" + newSpot.position[0] + "," + newSpot.position[1] + "]后,当前动点的状态:用时:" + newSpot.timeSpend + ",转向:" + newSpot.direction + ",面向:" + newSpot.FaceDirection);
//shorttime = newpqMoveSpot.peek().getTimeSpend();
System.out.println("2 "+shorttime);
}//边界内判断
}//四方向循环
}
/*
for (int i = 0; i < 10; i++) {
System.out.println("newpq检查:"+newpqMoveSpot.poll());
}
*/
shorttime = findMoveRoad(newpqMoveSpot, rowEnd, colEnd, lights, timePerRoad);
System.out.println("3 "+shorttime);
return shorttime;
}
//定义一个动点类
public static class MoveSpot {
private int[] position = new int[2];//位置 {row,col}
private int timeSpend;//用时
private int FaceDirection;//面向
private Move direction;//转向
public class FaceDirection{
public static final int NULL = -1;
public static final int UP = 0;
public static final int DOWN = 1;
public static final int LEFT = 2;
public static final int RIGHT = 3;
}
//转向枚举
public enum Move {
NoMoveDirection,GoStraight,TurnLeft,TurnRight;
}
//构造函数
public MoveSpot(int row , int col , int timeSpend, int faceDirection,Move direction) {
this.position[0] = row;//位置行列
this.position[1] = col;
this.timeSpend = timeSpend;
this.FaceDirection = faceDirection;
this.direction = direction;
}
//方法
//位置
public int[] getPosition() {
return position;
}
public void setPosition(int row, int col) {
this.position[0] = row;
this.position[1] = col;
}
//时间
public int getTimeSpend() {
return timeSpend;
}
public void setTimeSpend(int timeSpend) {
this.timeSpend = timeSpend;
}
//面向
public int getFaceDirection() {
return FaceDirection;
}
public void setFaceDirection(int faceDirection) {
FaceDirection = faceDirection;
}
//转向
public Move getDirection() {
return direction;
}
public void setDirection(Move direction) {
this.direction = direction;
}
//输出
public String toString(){
return "汽车"+ "到达["+position[0]+","
+position[1]+"]处"
+",用时为"+timeSpend
+",当前面向为:"+FaceDirection
+",当前行动状态为"+direction+"。";
}
}
}