代码随想录算法训练营第六十六天| 图论11—卡码网97. 小明逛公园,127. 骑士的攻击

继续补,又是两个新算法,继续进行勉强理解,也是训练营最后一天了,六十多天的刷题告一段落了!

97. 小明逛公园

97. 小明逛公园

感觉还是有点难理解原理

Floyd 算法对边的权值正负没有要求,都可以处理。核心思想是动态规划。我们求节点1 到 节点9 的最短距离,用二维数组来表示即:grid19,如果最短距离是10 ,那就是 grid19 = 10。

节点1到节点9 的最短距离可以由 节点1 到节点5的最短距离 + 节点5到节点9的最短距离组成grid19 = grid15 + grid59。节点1到节点5的最短距离可以节点1到节点3的最短距离 + 节点3 到 节点5 的最短距离组成即 grid15 = grid13 + grid35

因为代码是DP,所以有种很熟悉的感觉。首先初始化DP数组。重点是在理解三重循环

最外层k: 中转点选择当前允许使用的中转节点。假设你正在考虑是否可以使用 k 来让路径从 ij 更短。相当于说:如果我允许走"经过 k",会不会让i到j更快?后续的i是出发点,j是结束点,开始遍历整个路径。

  • "不经过 k" 的原始路径是 grid[i][j]

  • "经过 k" 的路径是 grid[i][k] + grid[k][j]

python 复制代码
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])

127. 骑士的攻击

127. 骑士的攻击

稍微容易理解的一种算法,但是感觉每天花时间去理解两种算法有点脑容量不足。A(A-Star)算法的路径搜索实现 *,用于求国际象棋中"马"(Knight)从一个点跳到另一个点的最少步数。首先还是定义移动方式,还是有点像DP刚开始的定义,使用欧几里得距离作为启发函数(h(n)),估计当前点到目标点的"直线距离"。这个就是判断路径是否变小的一个依据。移动的算法采用bfs,实际是**A* 算法 + 优先队列(堆)**的方法。每次在每个点尝试各个方向移动马,同时要进行欧几里得距离判断来看是否距离更短

python 复制代码
import heapq
 
n = int(input())
 
moves = [(1, 2), (2, 1), (-1, 2), (2, -1), (1, -2), (-2, 1), (-1, -2), (-2, -1)]
 
def distance(a, b):
    return ((a[0] - b[0]) ** 2 + (a[1] - b[1]) ** 2) ** 0.5
 
def bfs(start, end):
    q = [(distance(start, end), start)]
    step = {start: 0}
     
    while q:
        d, cur = heapq.heappop(q)
        if cur == end:
            return step[cur]
        for move in moves:
            new = (move[0] + cur[0], move[1] + cur[1])
            if 1 <= new[0] <= 1000 and 1 <= new[1] <= 1000:
                step_new = step[cur] + 1
                if step_new < step.get(new, float('inf')):
                    step[new] = step_new
                    heapq.heappush(q, (distance(new, end) + step_new, new))
    return False
                     
for _ in range(n):
    a1, a2, b1, b2 = map(int, input().split())
    print(bfs((a1, a2), (b1, b2)))
相关推荐
人工智能培训33 分钟前
人工智能数据安全下的个人信息保护实践方案
大数据·人工智能·算法·生活
元启数宇1 小时前
幕墙AI设计算法逻辑:元启数宇如何智能分格
人工智能·算法
宵时待雨1 小时前
优选算法专题16:多源BFS
算法·宽度优先
重生之后端学习2 小时前
53. 最大子数组和[中等]✅
java·数据结构·算法·leetcode·职场和发展
INGNIGHT2 小时前
1908 · 布尔表达式求值(stack单调栈&dfs)
开发语言·c++·算法
lucas_AI2 小时前
把表格压成 64 个 token,长文档问答反而更准了:先找表,再看数
人工智能·深度学习·算法
Zzz 小生3 小时前
Lazy Theta*:把昂贵的视线检测留到“真正需要”时再做
人工智能·算法·贪心算法·推荐算法
l1258653 小时前
# LangGraph Deep Research Agent 全流程设计:多轮研究、人机协同与真实来源管理
数据库·人工智能·python·算法·自然语言处理·oracle·langchain
青少儿编程课堂4 小时前
图形化编程实战:智能交通灯调度台,一个作品讲透循环、条件与广播
c++·python·算法·bfs·信息学竞赛
evans在进步4 小时前
LeetCode 438 找到字符串中所有字母异位词:滑动窗口与排序解法详解
算法·leetcode·职场和发展