题目描述
假定街道是棋盘型的,每格距离相等,车辆通过每格街道需要时间均为 timePerRoad;
街道的街口(交叉点)有交通灯,灯的周期 T(=lights[row][col])各不相同;
车辆可直行、左转和右转,其中直行和左转需要等相应 T 时间的交通灯才可通行,右转无需等待。
现给出 n * m 个街口的交通灯周期,以及起止街口的坐标,计算车辆经过两个街口的最短时间。
其中:
- 起点和终点的交通灯不计入时间,且可以在任意方向经过街口
- 不可超出 n * m 个街口,不可跳跃,但边线也是道路(即:lights[0][0] -> lights[0][1] 是有效路径)
入口函数定义:
/**
* @param lights:n*m个街口每个交通灯的周期,值范围[0, 120],n和m的范围为[1,9]
* @param timePreRoad:相邻两个街口之间街道的通行时间,范围为[0,600]
* @param rowStart:起点的行号
* @param colStart:起点的列号
* @param rowEnd:终点的行号
* @param colEnd:终点的列号
* @return lights[rowStart][colStart] 与 lights[rowEnd][colEnd] 两个街口之间的最短通行时间
*/
int calcTime(int[][] lights, int timePreRoad, int rowStart, int colStart, int rowEnd, int colEnd)
输入描述
第一行输入 n 和 m,以空格分隔
之后 n 行输入 lights矩阵,矩阵每行m个整数,以空格分隔
之后一行输入 timePerRoad
之后一行输入 rowStart colStart,以空格分隔
最后一行输入 rowEnd colEnd,以空格分隔
输出描述
lights[rowStart][colStart] 与 lights[rowEnd][colEnd] 两个街口之间的最短通行时间
示例1
输入
3 3
1 2 3
4 5 6
7 8 9
60
0 0
2 2
输出
245
说明
行走路线为 (0,0) -> (0,1) -> (1,1) -> (1,2) -> (2,2) 走了4格路,2个右转,1个左转,共耗时 60+0+60+5+60+0+60=245
思路
-
暴力解法回溯出所有路线,计算距离
-
在有权图(权值非负数)中求从起点到其他节点的最短路径算法: dijkstra 算法(dijkstra 算法可以同时求 起点到所有节点的最短路径)
dijkstra:
- 第一步,选源点到哪个节点近且该节点未被访问过
- 第二步,该最近节点被标记访问过
- 第三步,更新非访问节点到源点的距离(即更新minDist数组)
注意:到达当前节点的最短距离,不一定能推导出下一个节点的最小距离
例如: 到达(1,2)的距离(0,0) -> (0,1) -> (0,2) ->(1,2) : 60*3+2+0 = 182;比(0,0) -> (0,1) -> (1,1) -> (1,2) 60*3+5+0 = 185; 182的线路小,但是这个线路不能推导出(2,2)的最优解, 所以minDist在存储时不能只存储距离,还要存储方向信息。
方向编号处理: 顺时针规定方向编号,从0开始
路口编号处理: 按照先行后列设置编号,从0开始(目的为了降低数组维度,降低for循环嵌套)
代码
public class Demo20 {
// 方向顺序
private static final int[][] dir = new int[][] {
{
-1, 0},
{
0, 1},
{
1, 0},
{
0, -1},
};
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
while (in.hasNextInt()) {
int rows = in.nextInt();
int cols = in.nextInt();
int[][] lights = new int[rows][cols];
for (int i = 0; i < rows

最低0.47元/天 解锁文章
772

被折叠的 条评论
为什么被折叠?



