力扣289. 生命游戏

模拟 + 染色

  • 思路:
    • 可以复制一个表格,然后根据规则两层循环模拟出结果,但是空间复杂度太高;
    • 可以复用原有数组,对其进行染色标记;
      • 最终状态是活的标记值 > 1,还原标记值时可以使用规则 val > 0
      • 之前是活的现在是死的,标记成 -1,统计活细胞时可以使用规则 abs(val) = 1
    • 根据规则归纳:
      • R1:如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡,状态由 live 变成 die,用 -1 标记;(原状态是 live,需要被统计成活细胞)
      • R2:如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活,状态没有发生变化;
      • R3:如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡,状态由 live 变成 die,用 -1 标记;(原状态是 live,需要被统计成活细胞)
      • R4:如果死细胞周围正好有三个活细胞,则该位置死细胞复活,状态由 die 变成 live,用 2 标记;(最终状态是 live)
    • 进行两次两重循环遍历:
      • 第一次进行染色;
      • 第二次染色还原;
cpp 复制代码
class Solution {
public:
    void gameOfLife(vector<vector<int>>& board) {
        int row = board.size();
        if (0 == row) {
            return;
        }
        int column = board[0].size();
        if (0 == column) {
            return;
        }

        for (int r = 0; r < row; ++r) {
            for (int c = 0; c < column; ++c) {
                int live = 0;
                // statistics neighbors
                
                if (r > 0 && c > 0) {
                    // direct NW
                    if (std::abs(board[r - 1][c - 1]) == 1) {
                        live++;
                    }
                }
                if (r > 0) {
                    // direct N
                    if (std::abs(board[r - 1][c]) == 1) {
                        live++;
                    }                    
                }
                if (c > 0) {
                    // direct W
                    if (std::abs(board[r][c -1]) == 1) {
                        live++;
                    }
                }
                if (r + 1 < row) {
                    if (c > 0) {
                        // direct SW
                        if (std::abs(board[r + 1][c - 1]) == 1) {
                            live++;
                        }
                    }

                    // direct S
                    if (std::abs(board[r + 1][c]) == 1) {
                        live++;
                    }
                }
                if (c + 1 < column) {
                    // direct E
                    if (std::abs(board[r][c + 1]) == 1) {
                        live++;
                    }
                    if (r > 0) {
                        // direct NE
                        if (std::abs(board[r - 1][c + 1]) == 1) {
                            live++;
                        }
                    }
                    // direct SE
                    if (r + 1 < row) {
                        // direct NE
                        if (std::abs(board[r + 1][c + 1]) == 1) {
                            live++;
                        }
                    }
                }


                // rule 1 & 3
                if (board[r][c] == 1 && (live < 2 || live > 3)) {
                    // mark live -> die
                    board[r][c] = -1;
                }
                // rule 4
                if (board[r][c] == 0 && live ==  3) {
                    // mark die -> live
                    board[r][c] = 2;
                }
            }
        }

        // recover
        for (int r = 0; r < row; ++r) {
            for (int c = 0; c < column; ++c) {
                if (board[r][c] > 0) {
                    board[r][c] = 1;
                } else {
                    board[r][c] = 0;
                }
            }
        }
    }
};
  • 统计活细胞数量的逻辑比较朴素,可以进一步归纳美化;
相关推荐
游乐码9 小时前
Unity基础(六)小案例
游戏·unity·游戏引擎
无相孤君9 小时前
我用 Docker + JunimoServer 搭了一个星露谷物语无头服,还顺手做了个本地管理面板
linux·游戏·docker·开源
xifangge202510 小时前
Steam/Epic 游戏启动报错 0xc000007b / msvcp140.dll 缺失?VC++ 运行库底层修复指南
开发语言·c++·游戏
a588081110 小时前
星际争霸1原版安装包——游戏玩法、配置要求与详细安装教程
windows·游戏·游戏程序
littleschemer10 小时前
Go:实现游戏服务器网关
服务器·网关·游戏·golang
魔法阵维护师13 小时前
从零开发游戏需要学习的c#模块,第二十三章(粒子效果 —— 让游戏“活”起来本课目标)
学习·游戏·c#
魔法阵维护师13 小时前
从零开发游戏需要学习的c#模块,第二十二章(音效与背景音乐)
学习·游戏·c#
wanhengidc1 天前
私有云的作用都有哪些?
运维·服务器·网络·游戏·智能手机
魔法阵维护师1 天前
从零开发游戏需要学习的c#模块,第十六章(安装 MonoGame 并创建第一个窗口)
学习·游戏·c#·monogame
qq_265153371 天前
Redis在游戏服务器中怎么实现开合服数据同步?
服务器·redis·游戏·游戏服务器