289. 生命游戏

根据 百度百科 ,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在 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]
]
 

进阶:

你可以使用原地算法解决本题吗?请注意,面板上所有格子需要同时被更新:你不能先更新某些格子,然后使用它们的更新后的值再更新其他格子。
本题中,我们使用二维数组来表示面板。原则上,面板是无限的,但当活细胞侵占了面板边界时会造成问题。你将如何解决这些问题?

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/game-of-life
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
如果死细胞周围正好有三个活细胞,则该位置死细胞复活;

4个条件,可以简化成

1.如果当前是活的,周围少于2个,多余3个的,下一波就会死

2.如果当前是死的,周围有2个或者3个的,下一波会活

3.其他的姿态保持不变

把(1)会死的设置为2,但是当前还是活的,所以值要大于0

把(2)会活过来的设置为-1,可当前还是死的,要小于0

if (board[y][x] == 0 && sum == 3) 
  board[y][x]
= -1;//可复活

else if (board[y][x] == 1 && (sum < 2 || sum > 3))   board[y][x] = 2;//要死了

设置sum表示周围8格的总数,只要大于0的变+1

            for (int index = 0; index < 8; ++index)
            {
                if (x + x_index[index] < 0 || x + x_index[index] >= x_size || y + y_index[index] < 0 || y + y_index[index] >= y_size) 
                    continue;
                if (board[y + y_index[index]][x + x_index[index]] > 0) 
                    sum++;
            }

最后再循环一遍,把2改为0,把-1改为1,其他的不变

    for (int y = 0; y < y_size; ++y)
    {
        for (int x = 0; x < x_size; ++x)
        {
            if (board[y][x] == -1) 
                board[y][x] = 1;
            else if (board[y][x] == 2) 
                board[y][x] = 0;
        }
    }

所有代码如下:

    if (board.size() == 0) return;

    int x_size = board[0].size();
    int y_size = board.size();
    int x_index[8] = { -1, 0, 1, -1,1, -1,0,1 };
    int y_index[8] = { -1,-1,-1, 0, 0, 1,1,1 };

    for (int y = 0; y < y_size; ++y)
    {
        for (int x = 0; x < x_size; ++x)
        {
            int sum(0);
            for (int index = 0; index < 8; ++index)
            {
                if (x + x_index[index] < 0 || x + x_index[index] >= x_size || y + y_index[index] < 0 || y + y_index[index] >= y_size) 
                    continue;
                if (board[y + y_index[index]][x + x_index[index]] > 0) 
                    sum++;
            }
            
            if (board[y][x] == 0 && sum == 3) 
                board[y][x] = -1;//可复活
            else if (board[y][x] == 1 && (sum < 2 || sum > 3)) 
                board[y][x] = 2;//要死了
            printf(" %d 
", board[y][x]);
        }
    }
    for (int y = 0; y < y_size; ++y)
    {
        for (int x = 0; x < x_size; ++x)
        {
            if (board[y][x] == -1) 
                board[y][x] = 1;
            else if (board[y][x] == 2) 
                board[y][x] = 0;
        }
    }
原文地址:https://www.cnblogs.com/gongkiro/p/12619341.html