跳马问题(200)
- 输入m, n 表示一个m*n的棋盘,棋盘中存在 数字和. 两种符号,数字表示该位置的马可以走的最大步子,. 表示该位置为空;
- 马移动走“日”字,同中国象棋中的马移动;多个马可以移动到同一位置;
- 能否将棋盘上所有的马移动到同一个位置,若可以则输出最小的移动步数,若不可以输出0;
输入描述:
输入m n
输入m行数据
输出描述:
所有马移动到同一位置的最小步数,或者 0
示例1
输入:
3 2
. .
2 .
. .
输出:
0
示例2
输入:
3 5
4 7 . 4 8
4 7 4 4 .
7 . . . .
输出:
17
思路:
- 马走“日”,对应八个方向
- BFS 获取每个马走到m*n棋盘中每个点的步数;
- 所有马到每个点的步数相加,取最小值 (所有马均可到的点中取步数求和的最小值)
# 马走的方向
directions = [(-2, 1), (-2, -1), (1, 2), (1, -2), (-1, 2), (-1, -2), (2, 1), (2, -1)]
m, n = list(map(int, input().strip().split()))
# result 统计 所有马 的步数之和
result = [[0 for _ in range(n)] for _ in range(m)]
# BFS 每个马到所有点走的步子数,走不到的用-1表示
matrix = [[-1 for _ in range(n)] for _ in range(m)]
def init_matrix(): # 恢复为-1, 用于统计下一个马的步子数
global m, n, matrix
for i in range(m):
for j in range(n):
matrix[i][j] = -1
# 累加每个马的步子数
def update_result() :
global m, n, matrix, result
for i in range(m):
for j in range(n):
if matrix[i][j] == -1 or result[i][j] == -1: # 有马 无法走到该点位置 (所有马走到该位置则不可能)
result[i][j] = -1 # 表示无法完成所有马到达该点
else:
result[i][j] += matrix[i][j]
def bfs(i, j, step): # i,j起始点 step 可以走的步子数
global matrix, m, n
matrix[i][j] = 0
queue = [] # 队列
queue.append([i, j])
used_step = 1
while queue and used_step <= step:
size = len(queue)
for k in range(size):
current = queue.pop(0)
for l in range(8): # 遍历走八个方向
next_i = current[0] + directions[l][0]
next_j = current[1] + directions[l][1]
if 0 <= next_i and next_i < m and 0 <= next_j \
and next_j < n and matrix[next_i][next_j] == -1:
matrix[next_i][next_j] = used_step
queue.append([next_i, next_j])
used_step += 1
# 输入m行数据,并BFS搜索、累加
for i in range(m):
inputs = input().strip().split()
for j in range(n):
if inputs[j] != ".": # 有马
init_matrix()
bfs(i, j, int(inputs[j]))
update_result()
# 最终输出结果
output = float("inf")
for i in range(m):
for j in range(n):
if result[i][j] != -1:
output = min(output, result[i][j])
if output == float("inf"):
print(0)
else :
print(output)