请佩戴好口罩
题目描述
疫情当下,希望同学们都认真佩戴口罩,保护自己,保护他人。
现假设有一个n*n的网格,每个人分别站在网格中的一个方格上,人们可以选择佩戴/不佩戴口罩,口罩对于病毒的传播有如下影响,分为两种情况:
1. 某人已被感染,若未佩戴口罩,则病毒的“传染区域”是患者周围的四个方格;若正确佩戴口罩,则病毒无法传染其他人。
2. 某人健康,若未佩戴口罩,则只要他位于任意一个患者的“传染区域”内,就会被传染;若正确佩戴口罩,则只有他同时位于4个患者的“传染区域”内时,才会被传染。
我们将给出网格中每个人的口罩佩戴情况,以及网格中第一个患者的位置,请你计算d天后共有多少患者。
关于输入
第一行输入正整数n,表示网格的边长,1<=n<=100。
接下来输入网格,n行,每行n个整数,0表示未佩戴口罩,1表示佩戴口罩。
接下来一行是两个整数,表示第一个感染者在网格中的行、列坐标(规定网格左上角格子的坐标为(0, 0),右上角格子的坐标为(0, n-1),以此类推)。
接下来一行是一个正整数,表示天数d,1<=d<=100。
关于输出
输出为一行整数,表示经过d天后患者的人数。
例子输入
4 0 0 0 1 0 1 0 0 1 0 0 1 0 0 1 0 1 2 5
例子输出
11
解题分析
在python中直接用多层for循环是很慢的,Python是一种解释型语言,相对于编译语言,解释器需要更多的时间来解析和执行代码。此外,对于每一次循环迭代,Python需要进行更多的工作,例如变量查找、内存分配等。所以,本题如果直接定义一些数组存储信息,并用for循环去做的话,也不是不可以,只是在对于数据量比较大的情况下,会导致时间上开销极大。
下面介绍一种利用队列数据结构来优化的方法。我们可以引入队列(queue)数据结构,这个结构的特点是头出尾进,也就是它只能从尾巴进入队列,从队头离开队列。这是可以用数组去模拟的。只要我们在全局过程中维护好我们的一些下标变量和整个的数组结构即可。
我们还需要一个病人类记录发病的人的位置和发病的天数,以便我们去判断。
首先通过输入获取了网格的边长n以及网格中每个人的口罩佩戴情况,以及第一个患者的位置和天数d。然后使用了队列的数据结构,将第一个患者的位置和天数加入到队列中,并标记其口罩佩戴情况。接着,通过一个while循环,不断遍历队列中的元素,每次遍历时,都会将患者的传染区域内的健康人标记为2,同时将传染区域的健康人加入到队列中,并标记其天数。在遍历的过程中,通过不断pop()和push()操作,实现了对队列中元素的处理。最后,通过对网格中每个人的口罩佩戴情况进行遍历,计算出经过d天后患者的人数,并输出。
代码实现
count=1
n=int(input())
mask=[[0 for _ in range(n)] for _ in range(n)]
dx=[0,0,-1,1]
dy=[-1,1,0,0]
for i in range(n):mask[i]=list(map(int,input().split()))
x1,y1=map(int,input().split())
days=int(input())
d=1
count=1
q=[]
l=0
class sick:def __init__(self,x1,y1,d):self.x=x1self.y=y1self.day=d
q.append(sick(x1,y1,1))
if mask[x1][y1]==1:print(1)exit()
mask[x1][y1]=2
def pop():global ll+=1
def front():global lreturn q[l]
def push(x):q.append(x)
while l<len(q) and d<=days:p=front()while p.day==d:for i in range(4):nx=p.x+dx[i]ny=p.y+dy[i]if nx>=0 and nx<n and ny>=0 and ny<n and mask[nx][ny]==0:count+=1if d!=days:mask[nx][ny]=2else:mask[nx][ny]=3push(sick(nx,ny,d+1))pop()if l>=len(q):breakp=front()d+=1
for i in range(n):for j in range(n):if mask[i][j]==1:tmp=0for k in range(4):nx=i+dx[k]ny=j+dy[k]if nx>=0 and nx<n and ny>=0 and ny<n and mask[nx][ny]==2:tmp+=1if tmp==4:count+=1
print(count)