输入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}`]) {// 如果走过, 判断usedStepconst pastUsedStep = couldArrivePositions[`${positionRow},${positionCol}`];// 如果当前步数更少,则更新步数if (usedStep + 1 < pastUsedStep) {couldArrivePositions[`${positionRow},${positionCol}`] = usedStep + 1;}}// 如果没有走过则直接放入else {couldArrivePositions[`${positionRow},${positionCol}`] = usedStep + 1;}// 八个方向发BFSfor (let i = 0; i < directions.length; i++) {BFS(positionRow + directions[i][0], positionCol + directions[i][1], usedStep + 1, leftStep - 1, couldArrivePositions);}
}