Skip to content

12560: 生存游戏

matrices, http://cs101.openjudge.cn/practice/12560/

有如下生存游戏的规则:

给定一个n*m(1<=n,m<=100)的数组,每个元素代表一个细胞,其初始状态为活着(1)或死去(0)。

每个细胞会与其相邻的8个邻居(除数组边缘的细胞)进行交互,并遵守如下规则:

任何一个活着的细胞如果只有小于2个活着的邻居,那它就会由于人口稀少死去。

任何一个活着的细胞如果有2个或者3个活着的邻居,就可以继续活下去。

任何一个活着的细胞如果有超过3个活着的邻居,那它就会由于人口拥挤而死去。

任何一个死去的细胞如果有恰好3个活着的邻居,那它就会由于繁殖而重新变成活着的状态。

请写一个函数用来计算所给定初始状态的细胞经过一次更新后的状态是什么。

注意:所有细胞的状态必须同时更新,不能使用更新后的状态作为其他细胞的邻居状态来进行计算。

输入

第一行为n和m,而后n行,每行m个元素,用空格隔开。

输出

n行,每行m个元素,用空格隔开。

样例输入

3 4
0 0 1 1
1 1 0 0
1 1 0 1

样例输出

0 1 1 0
1 0 0 1
1 1 1 0

来源:cs10116 final exam

加保护圈,八个邻居步长用dx,dy对表示。

python
dx = [-1, -1, -1, 0, 1, 1,  1,  0]
dy = [-1,  0,  1, 1, 1, 0, -1, -1]

def check(board, y, x):
    c = 0
    for i in range(8):
        nx = x + dx[i]
        ny = y + dy[i]
        c += board[ny][nx]
        
    if board[y][x] and (c<2 or c>3):
        return 0
    elif board[y][x]==0 and c==3:
        return 1
    
    return board[y][x]

n, m = map(int, input().split())

board=[]
board.append( [0 for x in range(m+2)] )
for _ in range(n):
    board.append([0] +[int(_) for _ in input().split()] + [0])
    
board.append( [0 for _ in range(m+2)] )
    
# in place solver
bn = [[0]*m for y in range(n)]
for i in range(n):
    for j in range(m):
        bn[i][j] = check(board, i+1, j+1)
        
for row in bn:
    print(*row)

2020fall-cs101,张一丹

1)加保护圈;2)查找,满足条件,替换。

python
def check(board, y, x):
    c = board[y-1][x-1]+board[y-1][x]+ board[y-1][x+1]+ \
        board[y][x-1]+board[y][x+1]+ \
        board[y+1][x-1]+board[y+1][x]+board[y+1][x+1]
    if board[y][x] and (c<2 or c>3):
        return 0
    elif board[y][x]==0 and c==3:
        return 1
    
    return board[y][x]

n, m = map(int, input().split())

board=[]
board.append( [0 for x in range(m+2)] )
for y in range(n):
    board.append([0] +[int(x) for x in input().split()] + [0])
    
board.append( [0 for x in range(m+2)] )

bn = [[0]*m for y in range(n)]
for y in range(n):
    for x in range(m):
        bn[y][x] = check(board, y+1, x+1)
        
for y in range(n):
    print(' '.join([str(x) for x in bn[y] ]))

不加保护圈写法,用min/max.

python
def check(board, i, j):
    r = 1
    row_s, row_e = max(0, i-r), min(n-1, i+r)
    col_s, col_e = max(0, j-r), min(m-1, j+r)
    neighbor_sum = -board[i][j]			#下面累积求和,加了自己,所以先减掉一次。
    for k in range(row_s, row_e+1):
        for l in range(col_s, col_e+1):
            neighbor_sum += board[k][l]
         
    if board[i][j] and (neighbor_sum<2 or neighbor_sum>3):
        return 0
    elif board[i][j]==0 and neighbor_sum==3:
        return 1
    
    return board[i][j]

n, m = map(int, input().split())

board=[]
for _ in range(n):
    board.append([int(_) for _ in input().split()])
    
bn = [[0]*m for y in range(n)]
for i in range(n):
    for j in range(m):
        bn[i][j] = check(board, i, j)
        
for row in bn:
    print(*row)