蓝桥杯 扩散【第十一届】【决赛】【B组】 python BFS 多种数据类型比较

想说的话

大家好🌼🌼,我是 @愿此后再无WA,可以叫我小A,也可以叫我愿愿💡💡,一位阳光帅小伙,对算法领域比较感兴趣。如果我的文章对您有用,欢迎持续关注,我们一起进步!🎈🎈

很抱歉各位😪😪,现离蓝桥杯比赛不到一个月时间,我临时改变了计划,转为全心备战蓝桥,因为这个省一对我来说太重要了,也是我最后一次机会,我一定要拿到手📌📌,那么这样的话我在博客上花的时间就会少了很多,也将导致博客文章质量明显下降,在此我给大家说声抱歉💥💥


🌟🌟这些日子我真的很开心,博客上能遇到一群志同道合的兄弟姐妹真的很幸福,没有你们的支持与鼓励我早就坚持不下去了,因为有你们我才能走的更远☀️☀️熬过这段时期我一定会回来的,爱你们❤️❤️

吐槽

可以说这是我遇到一道非常有价值的题目,跟以往题目带来的经验有所不同,其他的题目更多的是让你掌握一种做题思路,一种做题模板,而这道题让我懂得了如何使用更恰当的数据类型进行数据处理。总之,收获满满!!

扩散

在这里插入图片描述

分析

给出四个点求经过2020分钟后扩散成几个点了,以点为中心向四周扩散的话容易想到是要使用BFS实现。但如果使用BFS的话不是等四五秒就出结果的,而这又是5分的最后一道题,真的很考验考生的心理压力。我看到有个思路是通过回路求的,能想到这方法也是厉害,反正我是想不到的,所以就老老实实使用BFS解决吧。

这题套用BFS模板就能得出结果,难就难在如何才能更优的存储、使用数据。在以前,我从来没有考虑过这种问题,以为只要思路到位了,数据类型再怎么不同,效率都不会相差太大。直到现在,我终于意识到了自己的错误,幸好没有在比赛上面犯错,这一切都能补救。一开始BFS的队列跟标记点我都是用列表存储的,跑了二十分钟都没有出结果,然后就有朋友建议这要用队列来做,于是我特地学习了几种队列才回来。

经过不断调试,我知道了以后该用什么数据类型作为队列,该用什么数据类型存储数据了。

我们先看几组图:

线程队列+集合

在这里插入图片描述
使用线程队列作为BFS的队列,用集合存储坐标,跑了2分22秒得出结果。

列表+集合

在这里插入图片描述
使用列表作为BFS的队列,用集合存储坐标,跑了1分31秒得出结果。

双向队列+列表

在这里插入图片描述
使用双向队列作为BFS的队列,用列表存储坐标,跑了8分30秒没有得出结果,我强行停止了。

双向队列+字典

在这里插入图片描述
使用双向队列作为BFS的队列,用字典存储坐标,跑了55秒得出结果。

双向队列+集合

在这里插入图片描述

使用双向序列作为BFS的队列,用集合存储坐标,跑了49秒得出结果。

通过比较我们发现,不同的数据类型它的处理速度是不一样的。在队列模型中,最快的是deque双向队列,其次是列表,最后是线程队列,没想到列表不是最慢的。

如果要进行数据存储的话集合是最快的,其次是字典,最后时列表,所以进行数据存储的话不要再使用列表啦!(更正:涉及数据查找时不要在列表里面查找)

根据以上结论,以后的BFS可以使用deque+集合的形式进行计算。(更正:不是一定需要使用集合,如果进行大量的数据查找,需要使用 xx in xxx时就要使用集合,其他情况使用列表对走过的位置标记也是没问题的。)

代码

下面看下代码实现:

from collections import deque
import  datetime
start = datetime.datetime.now()
visited = {(0,0),(2020,11),(11,14),(2000,2000)}
queue = deque([(0,0,0),(2020,11,0),(11,14,0),(2000,2000,0)])
result = 4
dx = (0,1,0,-1)
dy = (1,0,-1,0)

while True:
    x,y,cnt = queue.popleft()
    if cnt >= 2020:
        break
    
    cnt += 1
    for i in range(4):
        tx,ty = x+dx[i], y + dy[i]
        if (tx,ty) in visited: 
            continue
        queue.append((tx,ty,cnt))
        visited.add((tx,ty))
        result += 1
print(result)
end = datetime.datetime.now()
print(end-start)
  • 16
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

愿此后再无WA

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

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

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

打赏作者

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

抵扣说明:

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

余额充值