AcWing 845. 八数码 ( JavaScript )
原题链接
中等
作者:
gaobowen
,
2019-12-02 14:31:27
,
所有人可见
,
阅读 1215
思路:广度搜索+去除重复步骤
//存放走过了的方案
let dic = new Set();
const target = '12345678x';
let left = x => x % 3 ? x - 1 : null;
let top = x => x >= 3 ? x - 3 : null;
let right = x => x % 3 < 2 ? x + 1 : null;
let bottom = x => x < 6 ? x + 3 : null;
let move = [left, top, right, bottom];
let swap = (arr, a, b) => {
let t = arr[a];
arr[a] = arr[b], arr[b] = t;
}
let bfs = arr => {
let queue = [[arr, arr.indexOf('x')]];//存放当前网格状态与x位置
let step = -1;
while (queue.length > 0) {
step++;
let next = [];
for (let i = 0; i < queue.length; i++) {
let act = queue[i][0].join('');
let x = queue[i][1];
if (dic.has(act)) continue; //去重
if (act === target) return step;
dic.add(act);
for (let j = 0; j < 4; j++) { //4个方向
let y = move[j](x);
if (y !== null) {
let copy = [].concat(queue[i][0]);
swap(copy, x, y);
next.push([copy, y]);
}
}
}
queue = next;
}
return -1;
}
let buf = '';
process.stdin.on('readable', function () {
let chunk = process.stdin.read();
if (chunk) buf += chunk.toString();
});
let getInputNums = line => line.split(' ').filter(s => s !== '').map(x => parseInt(x));
let getInputStr = line => line.split(' ').filter(s => s !== '');
process.stdin.on('end', function () {
buf.split('\n').forEach(function (line, lineIdx) {
if (lineIdx === 0) {
let a = getInputStr(line);
console.log(bfs(a));
}
});
});