问题描述
曾经的我不过是一介草民,混迹市井,默默无名。直到我被罗马的士兵从家乡捉走丢进 竞技场
对手出现了,我架紧盾牌想要防御,只觉得巨大的冲击力有如一面城墙冲涌而来,击碎 了我的盾牌,我两眼发昏,沉重的身躯轰然倒地。
-- 我好想逃。
但罗马最大的竞技场,哪有这么容易逃得掉。工程师们早就在地上装了传送机关,虽不 会伤人,却会将站在上面的人传到它指向的位置。若是几个传送机关围成一个环,不小 心踩在上面的人就会被一圈圈地反复传送 ..... 想到这里,我不由得打了个寒颤。必须避 开这些危险的地方!
在一个NxM的竞技场迷宫中,你的任务是找出在迷宫中,所有“危险位置”的数量。
思路代码
def solution(N, M, data):
# Edit your code here
out = 0
rd = [[0]*(M+2)for _ in range(N+2)]
for i in range(N):
rd[i+1][0] = 'L'
rd[i+1][M+1] = 'R'
for j in range(M):
rd[i+1][j+1] = data[i][j]
if data[i][j] == 'O':
out = (i, j)
for i in range(M+2):
rd[0][i] = 'U'
rd[N+1][i] = 'D'
# 以上为数组补边,便于遍历输出,以免索引越界。至于为什么要补边而不是搜索的时候给索引加限定条件,
# 是因为反正想寻找出口也得遍历数组,干脆放在一起了。同时找出出口位置
edge = set()#目前的边界点
new_edge = set()#更新的边界点。开这个集合是因为在遍历edge的时候不能更新edge的内容
his = set()#记录历史的edge。开这个集合是为了让edge永远只有当前边,否则遍历的时候会有很多重复搜索。
edge.add(out)#初始边只有出口
le = 0#记录上一次的his的长度。如果扩散之后his长度未增长,说明全部的解已经找到了
while 1:
for item in edge:
i, j = item
if rd[i][j+1] in ('.', 'D'):
new_edge.add((i-1, j))
if rd[i+2][j+1] in ('.', 'U'):
new_edge.add((i+1, j))
if rd[i+1][j+2] in ('.', 'L'):
new_edge.add((i, j+1))
if rd[i+1][j] in ('.', 'R'):
new_edge.add((i, j-1))
le = len(his)
his.update(new_edge)
edge, new_edge = new_edge, edge
new_edge.clear()
if le == len(his):
break
#遍历整个edge,每次循环都会把edge“向外”扩散一次,扩散的点就是能到达出口的点。
return M*N-len(his)-1#不在his里的点就是无法到达出口的点。减一是因为出口算在里面
if __name__ == "__main__":
# Add your test cases here
pattern = [
[".", ".", ".", ".", "."],
[".", "R", "R", "D", "."],
[".", "U", ".", "D", "R"],
[".", "U", "L", "L", "."],
[".", ".", ".", ".", "O"]
]
print(solution(5, 5, pattern) == 10)
随便扯扯
思路都写在注释里了。
我是非科班出身,没学过深搜广搜,但是久闻大名。 今天在把我的代码喂给AI看的时候,他分析我使用的是广度优先搜索。我仔细一想,哦,好像真是那么回事儿,感觉还挺神奇的哈哈。佩服前人的智慧,能把一些普适的思想提炼出来,创造为体系结构。
另外,我真的很想吐槽,这个AI刷题的AI太傻了。一个索引越界的小bug扯了一堆莫须有的分析出来,还得我自己找bug。并且明明我已经改掉了,他还拿着这个问题复读。我说让他重新读一遍编辑区的代码吧,他居然拿着正确的代码跟我说这个问题仍然存在(他说一个M+2长度的数组读取M+1位置越界了,我????)
目前AI还是性能不够,并且很容易瞎编,代码逻辑稍微复杂一点点就不太行了。