题目描述
M行N列的地图, X
表示墙, .
表示空地, S
表示玩家位置, C
表示金币, O
表示箱子
玩家遇到箱子时, 可以推动箱子(前提是,箱子前面是空地), 一个箱子只能推动一次.
玩家起始位置也是为空地.
算法技巧
- 用深度优先搜索, 将可直接收集的金币清理掉
- 用广度优先搜索, 深度将所有可能的箱子推动一遍, 算出最多可收集的金币
- 遍历箱子, 需要用到回溯技巧
js算法实现
用js写是因为方便在浏览器上直接编程.
打开 https://js.do/, 将以下代码复杂上去, 就可以直接运行了
const X = 'X'; // 墙
const S = 'S'; // 玩家起始位置
const C = 'C'; // 金币
const _ = '.'; // 空地
const O = 'O'; // 箱子
const V = 'V'; // 可访问的空地
// 用于测试的地图, 总共可收集15个金币
const srcMap = [
'..XC..',
'..X.XX',
'CC.O..', // 2个金币
'XXX...',
'......',
'.OSX..',
'X.OCX.', // 1个金币
'...X..',
'XXX...',
'..X...',
'C.X...', // 无法收集
'..X...',
'XX....',
'....OX',
'...XC.', // 无法收集
'...XC.',
'....XX',
'......',
'.....O', // 无法收集
'....X.',
'...XC.',
'....XX',
'......',
'......',
'.....X',
'....OC',
'...X.C', // 3个金币
'..XCOC',
'..XXXX',
'.....X',
'....OC',
'...X.C', // 4个金币
'....OC', //
'..XXCX',
'....X.',
'......',
'XX.XXX',
'C.OXX.',
'CX...C', // 5个金币
'.X..OC', //
'.X.XCX',
'....X.',
];
// 四个方向移动时,x, y方向上的步伐
const dirs = [
{
x: 0, y: -1}, //向上移动
{
x: 0, y: +1, }, //向下移动
{
x: -1, y: 0, }, //向左移动
{
x: