蓝桥杯国赛 扩散(BFS-python)
题目描述
本题为填空题,只需要算出结果后,在代码中使用输出语句将所填结果输出即可。
小蓝在一张无限大的特殊画布上作画。
这张画布可以看成一个方格图,每个格子可以用一个二维的整数坐标表示。
小蓝在画布上首先点了一下几个点:(0, 0), (2020, 11), (11, 14), (2000, 2000)
只有这几个格子上有黑色,其它位置都是白色的。
每过一分钟,黑色就会扩散一点。具体的,如果一个格子里面是黑色,它就会扩散到上、下、左、右四个相邻的格子中,使得这四个格子也变成黑色(如果原来就是黑色,则还是黑色)。
请问,经过 2020分钟后,画布上有多少个格子是黑色的。
思路
这道题,首先我第一个思路就是可以利用BFS来解题,一级一级的扩散,一个时间一个时间的扩散,这样就可以很简单的得到最终结果
# https://www.lanqiao.cn/problems/1019/learning/ from collections import deque q = deque([(0,0),(2020,11),(11,14),(2000,2000)]) f = [(1,0),(-1,0),(0,1),(0,-1)] ans = 4 t = 2020 s = set() for x,y in q: s.add((x,y)) i = 0 while i < t: # 每一次需要扩散的点的数目 length = len(q) j = 0 while j < length: x,y = q.popleft() for nx,ny in f: nx = x + nx ny = y + ny if (nx,ny) not in s: ans += 1 s.add((nx,ny)) q.append((nx,ny)) j += 1 i += 1 print(ans)
但是我在看其他人做法的时候,发现有些方法是特别聪明的,由于我们是向上下左右扩散,画布也是无限的,所以几乎没有什么限制,所以我们只需要求,离我们已经画了的点距离2020就全是黑色的,这时候就不用BFS了,就是一个多重循环,这也是一个比较好的思想
# 扩散 #曼哈顿距离 #从A点只能上下移动到达B点需要的步数为:两点x的差的绝对值和两点y的差的绝对值相加。 spot, res = [[0,0], [2020,11], [11,14], [2000,2000]], 0 #虽然画布的大小是无限的,但是扩散的时间已明确,所以可知道所需画布的大小 for y in range(-2021,4022): for x in range(-2021,4042): #判断当前循环到的点是否在以上spot的点能触及到的范围 for s in spot: if abs(s[1]-y)+abs(s[0]-x) <= 2020: res += 1 #break是因为当前的(x,y)点已经有spot中的一个点扩散到了,不需要其他点再对它进行判断,避免重复累加。 break print(res)
所以最终答案就是
20312088