一维二维 扩散问题(python)

撒水问题是我们经常遇到的bfs的问题,在多少时间能扩散多少,和全部扩散到要花多少时间,这也是多bfs问题,下面是我做dfs问题的思路。

一维问题 (农田灌溉)

面对一维扩散问题,我们先了解,它可以向前走或者向后走,将其扩散到全部放在一个单独的函数中,进行判断使用的最大的时间,
请添加图片描述

请添加图片描述

1.输入------------创一个函数存放该地所要的时间
n,k=map(int,input().split())
a=list(map(int,input().split()))
b=[float('-inf')]*(n+1)
for i in a:
    b[i]=1
s=[-1,1]

2.进行bfs 算法进行广度遍历

这里要注意一点是,跳过已经遍历过的田地,因为原来算过的必定是最小的。

while a:
    t=a.pop(0)
    for i in s:
        x=i+t
        if 1<=x<=n  and b[x]==float('-inf'):  #跳过已经遍历过的只算该地区的最小值
            b[x]=b[t]+1
            a.append(x)
print(max(b))

二维扩散问题 (扩散)

请添加图片描述
这一道题要注意,用列表的话会发生超时,用python自带的队列进行计算,不过还是比较慢

1.输入

注意队列的时候不是仅仅是(x,y)在往后面加一个零,更方便我们对题目要求进行判断,什么时候可以跳出循环,类如题目给的2020次进行统计。ans是计算扩散的个数,跳出循环可以直接输出ans

import collections
dx = [-1, 1, 0, 0]
dy = [0, 0, 1, -1]
pre = {(0, 0): (0, 0), (2020, 11): (2020, 11), (11, 14): (11, 14), (2000, 2000): (2000, 2000)}
ans = 4
queue = collections.deque()
queue.append((0, 0, 0))
queue.append((2020, 11, 0))
queue.append((11, 14, 0))
queue.append((2000, 2000, 0))
bfs算法

当后面的0变成到2020时跳出循环,每扩散一次将其ans+=1

while queue:
    t = queue.popleft()
    if t[2] == 2020:
        print(ans)
        break
    else:
        for i in range(4):
            nx, ny = t[0] + dx[i], t[1] + dy[i]
            if (nx, ny) not in pre.keys():
                pre[(nx, ny)] = (t[0], t[1])
                queue.append((nx, ny, t[2] + 1))
                ans += 1
print(ans)
方法二暴力算法
x = [0, 2020, 11, 2000]
y = [0, 11, 14, 2000]
res = 0

for i in range(-2020, 4041):
    for j in range(-2020, 4041):
        for z in range(0, 4):
            if abs(x[z] - i) + abs(y[z] - j) <= 2020:
                res += 1
                break

print(res)

二维暴力算法 (灌溉)

请添加图片描述

请添加图片描述
实在不会做,可以考虑一下暴力解决,循环嘎嘎猛
暴力

1.输入
n,m=map(int,input().split())    
t=int(input())                  #2个出水口
a=[[0]*(m) for _ in range(n)]   #初始的方格
b=[[0]*(m) for _ in range(n)]   #灌溉后的方格
for i in range(t):
    r,c=map(int,input().split())
    a[r-1][c-1]=1               #初始化出水口
k=int(input())
2.暴力循环
for _ in range(k,0,-1):         #一分钟灌溉一次
    for i in range(n):
      for j in range(m):  
        if a[i][j]==1:
            b[i][j]=1           #中心值标记
            if i-1>=0:          #合格范围标记四个方向的水管
                b[i-1][j]=1
            if i+1<n:
                b[i+1][j]=1
            if j-1>=0:
                b[i][j-1]=1
            if j+1<m:
                b[i][j+1]=1
    a=b                         #灌溉完毕递归下一次
#输出
cnt=0
for i in b:
    for j in i:
        cnt+=j
print(cnt)    

解决扩散问题

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值