输入m和n 两个数,m和n表示一个mn 的棋盘。输入棋盘内的数据。棋盘中存在数字和".“两种字符,如果是数字表示Q该位置是一匹马,如果是”."表示该位置为空的,棋盘内的数字表示为该马能走的最大步数。例如棋盘内某个位置一个数字为k,表示该马只能移动1~k步的距离。
棋盘内的马移动类似于中国象棋中的马移动,先在水平或者垂直方向上移动一格,然后再将其移动到对角线位置。棋盘内的马可以移动到同一个位置,同一个位置可以有多匹马。
请问能否将棋盘上所有的马移动到同一个位置,若可以请输入移动的最小步数。若不可以输出0。输入描述
输入m 和n两个数,m和n表示一个mn的棋盘。输入棋盘内的数据。输出描述
能否将棋盘上所有的马移动到同一个位置,若可以请输入移动的最小步数。若不可以输出0。
该题不考虑绊马脚
js题解如下
const row = 3, col = 5;
const map = [
['4', '7', '.', '4', '8'],
['4', '7', '4', '4', '.'],
['7', '.', '.', '.', '.'],
]
const directions = [[1, 2], [1, -2], [2, 1], [2, -1], [-1, 2], [-1, -2], [-2, 1], [-2, -1]];
const horsePositionArray = []; // 有马的点
const horseCouldArrivePositionArray = []; // 与horsePositionArray一一对应
for (let i = 0; i < row; i++) {
for (let j = 0; j < col; j++){
// 计算马可以走到的所有位置
if (map[i][j] !== '.') {
// 马的坐标信息
const horseInfo = {
row: Number(i),
col: Number(j),
steps: Number(map[i][j]), // 可走步数
}
horsePositionArray.push(horseInfo);
const couldArrivePositions = {}
BFS(horseInfo.row, horseInfo.col, 0, horseInfo.steps, couldArrivePositions);
horseCouldArrivePositionArray.push(couldArrivePositions);
}
}
}
console.log(horsePositionArray);
console.log(horseCouldArrivePositionArray);
// 所有符合条件的点
const sucessPositions = [];
for (let i = 0; i < row; i++) {
for (let j = 0; j < col; j++){
const point = `${i},${j}`;
// console.log(point);
// 当前点是否存在于所有马的可达点
let allInclude = true;
// 遍历所有点,是否存在于所有马的
horseCouldArrivePositionArray.forEach(item => {
// console.log(!!item[point]);
if (!!item[point]) {
}
else {
allInclude = false;
return;
}
})
// 如果当前点所有马都可达,则放入
if (allInclude) {
sucessPositions.push(point);
}
}
}
console.log("所有符合条件的点", sucessPositions);
let minSumSteps = 0;
sucessPositions.forEach(sucessPoint => {
let sum = 0;
horseCouldArrivePositionArray.forEach(horseCouldArrivePositions => {
sum += horseCouldArrivePositions[sucessPoint]
})
if (minSumSteps === 0) {
minSumSteps = sum;
}
else if (sum < minSumSteps) {
minSumSteps = sum;
}
})
console.log('最终答案: ', minSumSteps - horsePositionArray.length)
// couldArrivePositions为对象, 属性格式为 'x,y': 'usedStep'
function BFS(positionRow, positionCol, usedStep, leftStep, couldArrivePositions) {
// console.log(positionRow, positionCol, usedStep, leftStep, couldArrivePositions);
// 判断是否超出边界
if (positionRow > row - 1 || positionCol > col - 1 || positionRow < 0 || positionCol < 0) {
return '超出边界';
}
// 判断有无剩余步数
if (leftStep == 0) {
return couldArrivePositions;
}
// 是否走过该点
if (couldArrivePositions[`${positionRow},${positionCol}`]) {
// 如果走过, 判断usedStep
const pastUsedStep = couldArrivePositions[`${positionRow},${positionCol}`];
// 如果当前步数更少,则更新步数
if (usedStep + 1 < pastUsedStep) {
couldArrivePositions[`${positionRow},${positionCol}`] = usedStep + 1;
}
}
// 如果没有走过则直接放入
else {
couldArrivePositions[`${positionRow},${positionCol}`] = usedStep + 1;
}
// 八个方向发BFS
for (let i = 0; i < directions.length; i++) {
BFS(positionRow + directions[i][0], positionCol + directions[i][1], usedStep + 1, leftStep - 1, couldArrivePositions);
}
}