流感传染

所属作业: hw7 数据结构: 列表

难点

  • 边界处理
  • 区分新感染的患者和以前感染的患者

正确写法

简单方法(1507ms)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 0. 读入
n = int(input())
matrix = []
for i in range(n):
    matrix.append(list(input()))
days = int(input())

directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]

# 1. 模拟传染
for i in range(days-1):
    for x in range(n):
        for y in range(n):
            for dx, dy in directions:
                nx, ny = x + dx, y + dy
                if 0 <= nx < n and 0 <= ny < n:
                    if matrix[x][y] == '.' and matrix[nx][ny] == '@':
                        matrix[x][y] = 'N'   # 用 N 来表示这是新感染的人
    for x in range(n):
        for y in range(n):
            if matrix[x][y] == 'N':
                matrix[x][y] = '@'   # 新感染的人可以感染别人了!
    
# 2. 统计感染人数
s = sum(line.count('@') for line in matrix)
print(s)

高级写法(189ms)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# 0. 读入
n = int(input())
matrix = []
healthy = []
for i in range(n):
    matrix.append(list(input()))
    for j in range(n):
        if matrix[i][j] == '.':
            healthy.append((i, j))
days = int(input())

directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]

# 1. 模拟传染
for i in range(days-1):
    infected = []
    for x, y in healthy:
        for dx, dy in directions:
            nx, ny = x + dx, y + dy
            if 0 <= nx < n and 0 <= ny < n:
                if matrix[x][y] == '.' and matrix[nx][ny] == '@':
                    infected.append((x, y))
                    break
    for x, y in infected:
        matrix[x][y] = '@'
        healthy.remove((x, y))
    
# 2. 统计感染人数
s = sum(line.count('@') for line in matrix)
print(s)

边界处理:填充字符(不推荐)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
n = int(input())

a = []
a.append(["#"]*(n+2))
for i in range(n):
    line = ["#"]+list(input())+["#"]
    a.append(line)
a.append(["#"]*(n+2)) # 原始矩阵

m = int(input())
for s in range(1,m): # 遍历m-1次
    for i in range(1,n+1): #
        for k in range(1,n+1):
            if a[i][k] == "@":
                if a[i-1][k]==".":
                    a[i - 1][k]=","
                if a[i][k-1]==".":
                    a[i][k - 1]=","
                if a[i+1][k]==".":
                    a[i+1][k]=","
                if a[i][k+1]==".":
                    a[i][k+1]=","
    for i in range(1,n+1):
        for j in range(1,n+1):
            if a[i][j]==",":
                a[i][j]="@"
count = 0
for i in range(1,n+1):
    for  j in range(1,n+1):
        if a[i][j]=="@":
            count += 1
print(count)

✨ 边界处理:if

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
n = int(input())
matrix = []   ##define a matrix
for i in range(n):
    line = input()
    line_ = []
    for sign in line:
        line_.append(sign)
    matrix.append(line_)

m = int(input())
#define a function, which means the pace of infection
def virus(x,y,virus_people):
    for (i,j) in [(x-1,y), (x+1,y), (x, y-1), (x, y+1)]:  ##rooms around
        if i < 0 or i >= n or j < 0 or j >= n:  ##set boundary conditions
            continue
        element = matrix[i][j]
        if element == '.':   ##added infected room into the list
            virus_people.append((i,j))

virus_sum = 0   #set sum of the infected people
for i in range(n):   ##record the initial number of infections
    for j in range(n):
        if matrix[i][j] == '@':
            virus_sum += 1
for day in range(m-1):  ##start the infect function
    virus_people = []
    for i in range(n):
        for j in range(n):
            if matrix[i][j] == '@':
                virus(i,j, virus_people)

    virus_people = list(set(virus_people))   ##remove individuals re-infected each time
    for x, y in virus_people:
        matrix[x][y] = '@'
    virus_sum += len(virus_people)
print(virus_sum)

区分新感染的患者和以前感染的患者

错误写法(原地修改矩阵导致出错)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
n = int(input())
lst_out = []
for _ in range(n):
    liver = input()
    lst_out.append(list(liver))

m = int(input())

for _ in range(m-3):
    for j in range(n):
        for k in range(n):
            if lst_out[j][k] == "@":
                if j > 0 and lst_out[j-1][k] == ".":
                    lst_out[j-1][k] = "@"
                if j < n-1 and lst_out[j+1][k] == ".":
                    lst_out[j+1][k] = "@"
                if k > 0 and lst_out[j][k-1] == ".":
                    lst_out[j][k-1] = "@"
                if k < n-1 and lst_out[j][k+1] == ".":
                    lst_out[j][k+1] = "@"

count2 = 0
for i in range(n):
    for j in range(n):
        if lst_out[i][j] == "@":
            count2 += 1

print(count2)

创建新矩阵

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
n = int(input())
matrix = []
for i in range(n):
    row = list(input())
    matrix.append(row)
m = int(input())

def count_flu(matrix):
    count = 0
    for row in matrix:
        for cell in row:
            if cell == '@':
                count += 1
    return count

def infect(matrix):
    n = len(matrix)
    m = len(matrix[0])
    new_matrix = []
    for i in range(n):
        new_row = []
        for j in range(m):
            if matrix[i][j] == '#':
                new_row.append('#')
            elif matrix[i][j] == '.':
                infected = False
                if i > 0 and matrix[i-1][j] == '@':
                    infected = True
                if i < n-1 and matrix[i+1][j] == '@':
                    infected = True
                if j > 0 and matrix[i][j-1] == '@':
                    infected = True
                if j < m-1 and matrix[i][j+1] == '@':
                    infected = True
                if infected:
                    new_row.append('@')
                else:
                    new_row.append('.')
            else:
                new_row.append('@')
        new_matrix.append(new_row)
    return new_matrix

for i in range(m-1):
    matrix = infect(matrix)

print(count_flu(matrix))

用N来表示新感染的同学

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 0. 读入
n = int(input())
matrix = []
for i in range(n):
    matrix.append(list(input()))
days = int(input())

directions = [(0, 1), (1, 0), (0, -1), (-1, 0)]

# 1. 模拟传染
for i in range(days-1):
    for x in range(n):
        for y in range(n):
            for dx, dy in directions:
                nx, ny = x + dx, y + dy
                if 0 <= nx < n and 0 <= ny < n:
                    if matrix[x][y] == '.' and matrix[nx][ny] == '@':
                        matrix[x][y] = 'N'   # 用 N 来表示这是新感染的人
    for x in range(n):
        for y in range(n):
            if matrix[x][y] == 'N':
                matrix[x][y] = '@'   # 新感染的人可以感染别人了!
    
# 2. 统计感染人数
s = sum(line.count('@') for line in matrix)
print(s)