前言
这是前两天od机试上遇到的大题,有点像迪杰斯特拉算法,但是又不太一样
题目描述
有一辆汽车需要从 m * n 的地图左上角(起点)开往地图的右下角(终点),去往每一个地区都需要消耗一定的油量,加油站可进行加油。
请你计算汽车确保从从起点到达终点时所需的最少初始油量。
说明:
- 智能汽车可以上下左右四个方向移动
- 地图上的数字取值是 0 或 -1 或 正整数:
- -1 :表示加油站,可以加满油,汽车的油箱容量最大为100;
- 0 :表示这个地区是障碍物,汽车不能通过
- 正整数:表示汽车走过这个地区的耗油量
- 如果汽车无论如何都无法到达终点,则返回 -1
输入描述
第一行为两个数字,M,N,表示地图的大小为 M * N
- 0 < M,N ≤ 200
后面一个 M * N 的矩阵,其中的值是 0 或 -1 或正整数,加油站的总数不超过 200 个
输出描述
如果汽车无论如何都无法到达终点,则返回 -1
如果汽车可以到达终点,则返回最少的初始油量
用例1
输入
2,2
10,20
30,40
输出
70
说明
行走的路线为:右→下
用例2
输入
4,4
10,30,30,20
30,30,-1,10
0,20,20,40
10,-1,30,40
输出
70
说明
行走的路线为:右→右→下→下→下→右
用例3
输入
4,5
10,0,30,-1,10
30,0,20,0,20
10,0,10,0,30
10,-1,30,0,10
输出
60
说明
行走的路线为:下→下→下→右→右→上→上→上→右→右→下→下→下
用例4
输入
4,4
10,30,30,20
30,30,20,10
10,20,10,40
10,20,30,40
输出
-1
说明
无论如何都无法到达终点
解答
下面代码目前只能通过部分用例,待优化。
/**
*
* 说明后续再给出,写了半天,头晕了
*
* */
// Example usage:
function getPath(grid) {
let arr = [];
let n = grid.length;
let m = grid[0].length;
let directions = [[0, 1], [0, -1], [1, 0], [-1, 0]]
// 如果要终点的油耗都超过了100,那么永远不可能到达,直接返回-1
if (grid[n - 1][m - 1] > 100) {
return -1;
}
// [当前坐标],[已访问坐标],当前油耗
let vPos = [n - 1, m - 1].join("|")
let item = [[n - 1, m - 1], [vPos], grid[n - 1][m - 1]];
// 终点为0,直接返回
if(!grid[n - 1][m - 1]) {
return -1;
}
insert(arr, item);
let x = n - 1;
let y = m - 1;
let lastTop = null;
while (arr.length) {
let top = arr.shift();
let curPos = top[0]
let x = curPos[0], y = curPos[1], fuel = top[2];
let visited = JSON.parse(JSON.stringify(top[1]));
// 到达起点
if (x == 0 && y == 0) {
// console.log(arr, 'arr');
return top;
}
let block = true;
for (let d of directions) {
let nX = x + d[0];
let nY = y + d[1];
let posStr = nX + '|' + nY;
// 判断是否访问过
let index = visited.indexOf(posStr)
// 越界或当前路径已经访问过,跳过
if (nX < 0 || nX >= n || nY < 0 || nY >= m || index > -1) {
// 越界
continue;
} else {
if (grid[nX][nY] == 0) {
continue;
} else if (grid[nX][nY] == -1) {
let visited = JSON.parse(JSON.stringify(top[1]));
let walkPos = [nX, nY].join("|");
visited.push(walkPos);
let item = [[nX, nY], visited, fuel, 0];
insert(arr, item);
block = false;
}
else {
let curFuel = fuel + grid[nX][nY];
let visited = JSON.parse(JSON.stringify(top[1]));
let walkPos = [nX, nY].join("|");
visited.push(walkPos);
let item = [[nX, nY], visited, curFuel];
insert(arr, item);
block = false;
}
}
}
if (block) {
back(arr, top, grid);
}
}
return -1;
}
function back(arr, top, grid) {
let curPos = top[0];
let visited = top[1]
let corPosStr = top[0].join("|");
let index = visited.indexOf(corPosStr);
let lastPos
if (index) {
lastPos = visited[index - 1];
}
if (!lastPos) {
return;
}
lastPos = lastPos.split("|").map((item) => parseInt(item));
let x = curPos[0], y = curPos[1];
if (x == grid.length - 1 && y == grid[0].length - 1) {
return;
}
let val = grid[x][y];
let curFuel = top[2];
if (val > 0) {
let item = [lastPos, top[1], curFuel - val];
insert(arr, item);
}
}
function insert(arr, item) {
for (let i = 0; i < arr.length; i++) {
if (arr[i][3] > item[3]) {
arr.splice(i, 0, item);
return;
}
}
arr.push(item);
}
function getMaxFuel(grid) {
var top = getPath(grid);
if (top == -1) {
return -1;
} else {
let routes = top[1];
let max = 0;
let cur = 0;
for (let i = routes.length - 1; i >= 0; i--) {
let item = routes[i];
let pos = item.split("|").map(val => parseInt(val));
let val = grid[pos[0]][pos[1]];
if (val == -1) {
cur = 0;
continue;
}
if (val == 0) {
debugger
}
cur += grid[pos[0]][pos[1]];
if (cur > max) {
max = cur;
}
}
if(max > 100) {
return -1;
}
return max;
}
}
var grid = [
[10, 0, 30, -1, 10],
[30, 0, 20, 0, 20],
[10, 0, 10, 0, 30],
[10, -1, 30, 0, 10]
];
console.log(getMaxFuel(grid)) // Outputs the minimum initial fuel needed
grid = [
[10, 30, 30, 20],
[30, 30, -1, 10],
[0, 20, 20, 40],
[10, -1, 30, 40]
]
console.log(getMaxFuel(grid)); // Outputs the minimum initial fuel needed
grid = [
[10, 20],
[30, 40]
]
console.log(getMaxFuel(grid)); // Outputs the minimum initial fuel needed
grid = [
[10, 30, 30, 20],
[30, 30, 20, 10],
[10, 20, 10, 40],
[10, 20, 30, 40]
]
console.log(getMaxFuel(grid)); // Outputs the minimum initial fuel needed
grid = [
[1, 1],
[1, 0]
]
console.log(getMaxFuel(grid)); // Outputs the minimum initial fuel needed
grid = [
[-1, -1],
[-1, -1]
]
console.log(getMaxFuel(grid)); // Outputs the minimum initial fuel needed