OD C卷 - 跳马问题

跳马问题(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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

laufing

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值