生命游戏
Posted olajennings
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了生命游戏相关的知识,希望对你有一定的参考价值。
根据 百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 1970 年发明的细胞自动机。
给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞都具有一个初始状态:1 即为活细胞(live),或 0 即为死细胞(dead)。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:
如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
如果死细胞周围正好有三个活细胞,则该位置死细胞复活;
根据当前状态,写一个函数来计算面板上所有细胞的下一个(一次更新后的)状态。下一个状态是通过将上述规则同时应用于当前状态下的每个细胞所形成的,其中细胞的出生和死亡是同时发生的。
示例:
输入:
[
[0,1,0],
[0,0,1],
[1,1,1],
[0,0,0]
]
输出:
[
[0,0,0],
[1,0,1],
[0,1,1],
[0,1,0]
]
进阶:
你可以使用原地算法解决本题吗?请注意,面板上所有格子需要同时被更新:你不能先更新某些格子,然后使用它们的更新后的值再更新其他格子。
本题中,我们使用二维数组来表示面板。原则上,面板是无限的,但当活细胞侵占了面板边界时会造成问题。你将如何解决这些问题?
class Solution { public: void gameOfLife(vector<vector<int>>& board) { int m = board.size(); int n = board[0].size(); int dx[8] = {-1,-1,-1,0,0,1,1,1}; int dy[8] = {-1,0,1,-1,1,-1,0,1}; for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++){ int cnt = 0; for(int k = 0; k < 8; k++){ int x = i + dx[k]; int y = j + dy[k]; if(0 <= x && x < m && 0 <= y && y < n){ if(board[x][y] > 0) cnt++; } } if(board[i][j] == 1){ if(cnt < 2 || cnt > 3) board[i][j] = 3; else board[i][j] = 2; } else{ if(cnt == 3) board[i][j] = -2; else board[i][j] = -1; } } } for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++){ if(board[i][j] == -2 || board[i][j] == 2) board[i][j] = 1; else board[i][j] = 0; } } } };
解题思路:
emmm,我觉得今天的题挺简单的,原地更新,那就是要我把更新前的状态也保留下来呗,增加状态就是了:
0 -> 0 :-1
0 -> 1 :-2
1 -> 1 : 2
1 -> 0 : 3
如果状态>0,那就说明更新前是活的,如果<0,那更新前就是死的
全部更新完后,再来一次整个矩阵的遍历,把状态为2或-2的设为1就好了,因为2和-2是更新后为活细胞的状态值,其他的设为0。
以上是关于生命游戏的主要内容,如果未能解决你的问题,请参考以下文章