美团笔试hard刷题笔记1

本文介绍了一种使用优先级队列和广度优先搜索策略解决图中两点间最短路径问题的方法。通过建立二维矩阵记录已访问状态,并结合剪枝优化避免重复遍历,最终实现nlogn的时间复杂度。博客详细讨论了如何根据交通灯规则动态调整路径,并给出了完整的Python代码实现。
摘要由CSDN通过智能技术生成

在这里插入图片描述

总结:一开始看到题很慌,感觉又是自己做不出的题了。但是还是没有放弃,试着用DP的思想理了下思路,逐步分析后发现越来越像类dij算法,这才灵感如泉涌,最终得出思路:

  1. 整体是广度优先搜索的策略,每次循环使用优先级队列pq维护的当前最近的点
  2. 并使用mat来记录已经遍历的结果,防止重复遍历。
  3. 加入剪枝优化,一旦出现需要的结果立刻跳出循环。
  4. 最终时间复杂度为nlogn量级,其中n为图中需遍历的点数,n小于等于 1 0 4 10^4 104
n, m, xs, ys, xt, yt = map(int, input().split())
a, b = [], []
for i in range(n):
 a.append(list(map(int, input().split())))
for i in range(n):
 b.append(list(map(int, input().split())))
# 准备工作
xt, yt = xt-1, yt-1
import heapq
pq = [(0, xs-1, ys-1)]
mat = [[-1]*m for i in range(n)]

# 用于计算对于当前时间当前十字路口那个方向可以通行,
# 同时返回去另一个方向需要等待的时间
def rule(t, i, j):
 ax, bx = a[i][j], b[i][j]
 t = t % (ax + bx)
 if t < ax:
     return True, ax - t
 else:
     return False, ax + bx - t
while pq:
 min_t, i, j = heapq.heappop(pq)
 if mat[i][j] != -1:
     continue
 mat[i][j] = min_t
 if i == xt and j == yt:
     ans = min_t
     break
 direc, t_w = rule(min_t, i, j)
 for step in [1, -1]:
     ni, nj = i + step, j + step
     if 0 <= nj < m:
         heapq.heappush(pq, (min_t + 1 + (t_w if direc else 0), i, nj))
     if 0 <= ni < n:
         heapq.heappush(pq, (min_t + 1 + (0 if direc else t_w), ni, j))
print(ans)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值