代码随想录算法训练营第六十二天|Floyd 算法精讲 、A * 算法精讲 (A star算法)

卡码网:97. 小明逛公园

基于三维数组:

if __name__ == '__main__':
    max_int = 10005  # 设置最大路径,因为边最大距离为10^4

    n, m = map(int, input().split())

    grid = [[[max_int] * (n+1) for _ in range(n+1)] for _ in range(n+1)]  # 初始化三维dp数组

    for _ in range(m):
        p1, p2, w = map(int, input().split())
        grid[p1][p2][0] = w
        grid[p2][p1][0] = w

    # 开始floyd
    for k in range(1, n+1):
        for i in range(1, n+1):
            for j in range(1, n+1):
                grid[i][j][k] = min(grid[i][j][k-1], grid[i][k][k-1] + grid[k][j][k-1])

    # 输出结果
    z = int(input())
    for _ in range(z):
        start, end = map(int, input().split())
        if grid[start][end][n] == max_int:
            print(-1)
        else:
            print(grid[start][end][n])

基于二维数组:

if __name__ == '__main__':
    max_int = 10005  # 设置最大路径,因为边最大距离为10^4

    n, m = map(int, input().split())

    grid = [[max_int]*(n+1) for _ in range(n+1)]  # 初始化二维dp数组

    for _ in range(m):
        p1, p2, val = map(int, input().split())
        grid[p1][p2] = val
        grid[p2][p1] = val

    # 开始floyd
    for k in range(1, n+1):
        for i in range(1, n+1):
            for j in range(1, n+1):
                grid[i][j] = min(grid[i][j], grid[i][k] + grid[k][j])

    # 输出结果
    z = int(input())
    for _ in range(z):
        start, end = map(int, input().split())
        if grid[start][end] == max_int:
            print(-1)
        else:
            print(grid[start][end])

卡码网:126. 骑士的攻击

import heapq
from itertools import product

# 定义骑士的移动方向
dir = [
    (-2, -1), (-2, 1), (-1, 2), (1, 2),
    (2, 1), (2, -1), (1, -2), (-1, -2)
]

# 骑士启发式函数(欧几里得距离,不进行开方,以提高精度)
def heuristic(k):
    return (k.x - b1) ** 2 + (k.y - b2) ** 2

# A*算法
def astar(start):
    # 优先队列,用于A*算法
    que = []
    # 已访问的节点字典,记录从起点到该点的路径消耗
    moves = {(start.x, start.y): 0}
    heapq.heappush(que, (start.g + start.h, start.g, start, None))

    while que:
        _, g, node, parent = heapq.heappop(que)
        if node.x == b1 and node.y == b2:
            break

        for dx, dy in dir:
            next_x, next_y = node.x + dx, node.y + dy
            if 1 <= next_x <= 1000 and 1 <= next_y <= 1000 and (next_x, next_y) not in moves:
                new_g = g + 5  # 移动消耗,马走日,1*1 + 2*2 = 5
                new_h = heuristic(Knight(next_x, next_y, new_g, None))
                new_f = new_g + new_h
                moves[(next_x, next_y)] = new_g
                heapq.heappush(que, (new_f, new_g, Knight(next_x, next_y, new_g, None), node))

    return moves[b1, b2]

# 定义骑士的状态,包含位置和代价
class Knight:
    def __init__(self, x, y, g, h):
        self.x = x
        self.y = y
        self.g = g  # 从起点到当前点的路径消耗
        self.h = h  # 启发式函数值
        self.f = g + h  # F = G + H

    def __repr__(self):
        return f"Knight(x={self.x}, y={self.y}, g={self.g}, h={self.h})"

# 主函数
def main():
    n = int(input())
    for _ in range(n):
        a1, a2, b1, b2 = map(int, input().split())
        start = Knight(a1, a2, 0, heuristic(Knight(a1, a2, 0, None)))
        result = astar(start)
        print(result)

if __name__ == "__main__":
    main()

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值