输入 m
和 n
两个数,m
和 n
表示一个 m*n
的棋盘。输入棋盘内的数据。棋盘中存在数字和"."
两种字符,如果是数字表示该位置是一匹马,如果是"."
表示该位置为空的,棋盘内的数字表示为该马能走的最大步数。
例如棋盘内某个位置一个数字为 k
,表示该马只能移动 1~k
步的距离。
棋盘内的马移动类似于中国象棋中的马移动,先在水平或者垂直方向上移动一格,然后再将其移动到对角线位置。
棋盘内的马可以移动到同一个位置,同一个位置可以有多匹马。
请问能否将棋盘上所有的马移动到同一个位置,若可以请输入移动的最小步数。若不可以输出 0
。
输入m
和 n
两个数,m
和 n
表示一个 m*n
的棋盘。输入棋盘内的数据。
能否将棋盘上所有的马移动到同一个位置,若可以请输入移动的最小步数。若不可以输出 0
。
3 2
. .
2 .
. .
0
3 5
4 7 . 4 8
4 7 4 4 .
7 . . . .
17
假设已知某匹马的坐标和最大跳跃步数,则可以用BFS计算出能够跳到该匹马能够用到达地图上某个点的最小步数。比如对于以下初始位于(0, 0)
位置最多能跳4
步的马
4 . . . .
. . . . .
. . . . .
考虑它跳跃到地图上各个点所花费的步数
跳跃0步
0 . . . .
. . . . .
. . . . .
跳跃1步
0 . . . .
. . 1 . .
. 1 . . .
跳跃2步
0 . 2 . 2
. . 1 2 .
2 1 . . 2
跳跃3步
0 3 2 3 2
3 . 1 2 3
2 1 . 3 2
跳跃4步
0 3 2 3 2
3 4 1 2 3
2 1 4 3 2
因此可以通过BFS过程得到这匹马可以到达的最终状态。其代码如下
from collections import deque
DIERECTIONS = [(1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1)]
def bfs4SingleHorse(i, j, m, n, step):
mat = [[-1] * n for _ in range*(m)]
mat[i][j] = 0
q = deque()
q.append((i, j))
level = 0
while q:
level += 1
if level > step:
break
qSize = len(q)
for _ in range(qSize):
cur_i, cur_j = q.popleft()
for di, dj in DIERECTIONS:
nxt_i, nxt_j = cur_i + di, cur_j + dj
if 0 <= nxt_i < m and 0 <= nxt_j < n and mat[nxt_i][nxt_j] == -1:
mat[nxt_i][nxt_j] = level
q.append((nxt_i, nxt_j))
return mat
对于每一匹马,都可以计算出对应的二维矩阵mat
。考虑多匹马的情况,将所有马的mat
叠加成一个总的二维矩阵ans_mat
,对于每一个点(x, y)
而言,其逻辑如下
ans_mat[x][y]
已经为-1
,说明有其他马无法到达点(x,y)
mat[x][y]
为-1
,说明这匹马无法到达点(x,y)
,将ans_mat[x][y]
改为-1
ans_mat[x][y]
和mat[x][y]
均不为-1
,则将mat[x][y]
叠加到ans_mat[x][y]
中考虑2
匹马的简单例子,可以从以下例子看出上述逻辑。假设初始矩阵为
3 . . . .
. . 1 . .
. . . . .
那么位置为(0, 0)
的马的最终可到达情况矩阵mat
为
0 3 2 3 2
3 . 1 2 3
2 1 . 3 2
位置为(1, 2)
的马的最终可到达情况矩阵mat
为
1 . . . 1
. . 0 . .
1 . . . 1
其中-1
用.
来表示。两者的叠加结果为
1 . . . 3
. . 1 . .
3 . . . 3
可以看出,所有马跳到同一个位置的最小的步数就为1
。
# 题目:【BFS】2023C-跳马问题
# 分值:200
# 作者:许老师-闭着眼睛学数理化
# 算法:BFS
# 代码看不懂的地方,请直接在群上提问
from collections import deque
from math import inf
# 马走”日“字型的八个方向数组
DIERECTIONS = [(1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1), (-2, 1), (-2, -1)]
# 单匹马进行BFS的函数
# (i, j)为马的起始位置
# step为马能够走的最大步数
def bfs4SingleHorse(i, j, m, n, step):
# 记录这匹最终的跳跃情况的数组,
# 初始化每一个位置为-1,表示暂且无法到达
# mat也同时可以作为check_list的作用
mat = [[-1] * n for _ in range(m)]
# 马所在的初始位置(i,j)设置到达步数为0
mat[i][j] = 0
q = deque()
q.append((i, j))
# BFS的层数,表示跳到某个位置需要的步数
level = 0
# 进行BFS
while q:
# 层数+1
level += 1
# 如果此时BFS的层数已经超过了这匹马能够跳跃的最大步数step
# 则直接退出循环
if level > step:
break
qSize = len(q)
# 遍历该层的所有点
for _ in range(qSize):
# 弹出队头元素,获得当前点(cur_i, cur_j)
cur_i, cur_j = q.popleft()
# 考虑当前点走“日”字型的八个方向
for di, dj in DIERECTIONS:
# 计算下一个点的到达位置(nxt_i, nxt_j)
nxt_i, nxt_j = cur_i + di, cur_j + dj
# 如果下一个点没有越界,且之前尚未经过(mat起到check_list的作用)
if 0 <= nxt_i < m and 0 <= nxt_j < n and mat[nxt_i][nxt_j] == -1:
# 把mat[nxt_i][nxt_j]修改为到达该点(nxt_i, nxt_j)的最小步数
mat[nxt_i][nxt_j] = level
# 同时该点也需要加入队列中,继续做BFS
q.append((nxt_i, nxt_j))
# 做完BFS,将mat传出函数外
return mat
# 输入地图的长m,宽n
m, n = map(int, input().split())
grid = list()
for _ in range(m):
# 输入地图,由于存在字符'.'
# 所以不需要转化成int整数,储存字符串数组即可
grid.append(list(input().split()))
# 初始化ans_mat,
# ans_mat[x][y]表示【所有马】到达点(x,y)所需的总步数
# 如果无法到达,则最终会被标记为-1
ans_mat = [[0] * n for _ in range(m)]
# 双重循环,遍历原grid中每一个点
for i in range(m):
for j in range(n):
# 如果这个点不是数字,则可以计算这匹马最终跳跃状态对应的mat
# 其中最大跳跃步数为int(grid[i][j])
if grid[i][j] != ".":
mat = bfs4SingleHorse(i, j, m, n, int(grid[i][j]))
# 对于算出来的mat,再次遍历每一个位置,更新ans_mat
for x in range(m):
for y in range(n):
# 如果ans[x][y]已经为-1,说明有其他马无法到达点(x,y)
# 如果mat[x][y]为-1,说明这匹马无法到达点(x,y)
# 无论是上述那种情况,都应该把ans_mat[x][y]改为-1
if mat[x][y] == -1 or ans_mat[x][y] == -1:
ans_mat[x][y] = -1
# 否则,将mat[x][y]的值叠加在ans_mat[x][y]中
else:
ans_mat[x][y] += mat[x][y]
# 最终需要输出的最终答案
ans = inf
# 遍历ans_mat中的每一个点,
# 计算出ans_mat中不为-1的最小值
for i in range(m):
for j in range(n):
if ans_mat[i][j] != -1 and ans > ans_mat[i][j]:
ans = ans_mat[i][j]
print(0 if ans == inf else ans)
import java.util.*;
class Main {
static class Pair {
int first;
int second;
Pair(int first, int second) {
this.first = first;
this.second = second;
}
}
static final int[][] DIRECTIONS = {{1, 2}, {1, -2}, {-1, 2}, {-1, -2}, {2, 1}, {2, -1}, {-2, 1}, {-2, -1}};
static int[][] bfs4SingleHorse(int i, int j, int m, int n, int step) {
int[][] mat = new int[m][n];
for (int[] row : mat) {
Arrays.fill(row, -1);
}
mat[i][j] = 0;
Queue<Pair> q = new LinkedList<>();
q.add(new Pair(i, j));
int level = 0;
while (!q.isEmpty()) {
level++;
if (level > step) {
break;
}
int qSize = q.size();
for (int k = 0; k < qSize; k++) {
Pair cur = q.poll();
for (int[] dir : DIRECTIONS) {
int ni = cur.first + dir[0];
int nj = cur.second + dir[1];
if (0 <= ni && ni < m && 0 <= nj && nj < n && mat[ni][nj] == -1) {
mat[ni][nj] = level;
q.add(new Pair(ni, nj));
}
}
}
}
return mat;
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int m = scanner.nextInt();
int n = scanner.nextInt();
scanner.nextLine(); // consume newline
String[][] grid = new String[m][n];
for (int i = 0; i < m; i++) {
String line = scanner.nextLine();
String[] tokens = line.split(" ");
for (int j = 0; j < n; j++) {
grid[i][j] = tokens[j];
}
}
int[][] ansMat = new int[m][n];
for (int[] row : ansMat) {
Arrays.fill(row, 0);
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (!grid[i][j].equals(".")) {
int[][] mat = bfs4SingleHorse(i, j, m, n, Integer.parseInt(grid[i][j]));
for (int x = 0; x < m; x++) {
for (int y = 0; y < n; y++) {
if (mat[x][y] == -1 || ansMat[x][y] == -1) {
ansMat[x][y] = -1;
} else {
ansMat[x][y] += mat[x][y];
}
}
}
}
}
}
int ans = Integer.MAX_VALUE;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (ansMat[i][j] != -1 && ans > ansMat[i][j]) {
ans = ansMat[i][j];
}
}
}
System.out.println((ans == Integer.MAX_VALUE) ? 0 : ans);
}
}
#include
#include
#include
#include
using namespace std;
const vector<pair<int, int>> DIRECTIONS = {{1, 2}, {1, -2}, {-1, 2}, {-1, -2}, {2, 1}, {2, -1}, {-2, 1}, {-2, -1}};
vector<vector<int>> bfs4SingleHorse(int i, int j, int m, int n, int step) {
vector<vector<int>> mat(m, vector<int>(n, -1));
mat[i][j] = 0;
queue<pair<int, int>> q;
q.push({i, j});
int level = 0;
while (!q.empty()) {
level++;
if (level > step) {
break;
}
int qSize = q.size();
for (int k = 0; k < qSize; k++) {
pair<int, int> cur = q.front();
q.pop();
for (auto &dir : DIRECTIONS) {
int ni = cur.first + dir.first;
int nj = cur.second + dir.second;
if (0 <= ni && ni < m && 0 <= nj && nj < n && mat[ni][nj] == -1) {
mat[ni][nj] = level;
q.push({ni, nj});
}
}
}
}
return mat;
}
int main() {
int m, n;
cin >> m >> n;
cin.ignore();
vector<vector<string>> grid(m, vector<string>(n));
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
cin >> grid[i][j];
}
}
vector<vector<int>> ansMat(m, vector<int>(n, 0));
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (grid[i][j] != ".") {
auto mat = bfs4SingleHorse(i, j, m, n, stoi(grid[i][j]));
for (int x = 0; x < m; x++) {
for (int y = 0; y < n; y++) {
if (mat[x][y] == -1 || ansMat[x][y] == -1) {
ansMat[x][y] = -1;
} else {
ansMat[x][y] += mat[x][y];
}
}
}
}
}
}
int ans = INT_MAX;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (ansMat[i][j] != -1 && ans > ansMat[i][j]) {
ans = ansMat[i][j];
}
}
}
cout << ((ans == INT_MAX) ? 0 : ans) << endl;
return 0;
}
时间复杂度:O((NM)^2)
。
空间复杂度:O(NM)
。
华为OD算法/大厂面试高频题算法冲刺训练目前开始常态化报名!目前已服务100+同学成功上岸!
课程讲师为全网50w+粉丝编程博主@吴师兄学算法 以及小红书头部编程博主@闭着眼睛学数理化
每期人数维持在20人内,保证能够最大限度地满足到每一个同学的需求,达到和1v1同样的学习效果!
60+天陪伴式学习,40+直播课时,300+动画图解视频,300+LeetCode经典题,200+华为OD真题/大厂真题,还有简历修改、模拟面试、专属HR对接将为你解锁
可上全网独家的欧弟OJ系统练习华子OD、大厂真题
可查看链接 大厂真题汇总 & OD真题汇总(持续更新)
绿色聊天软件戳 od1336
了解更多