力扣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;
                }
            }
        }
    }
};
  • 统计活细胞数量的逻辑比较朴素,可以进一步归纳美化;
相关推荐
阿阳微客5 小时前
Steam 搬砖项目深度拆解:从抵触到真香的转型之路
前端·笔记·学习·游戏
m0_5522008211 小时前
《UE5_C++多人TPS完整教程》学习笔记37 ——《P38 变量复制(Variable Replication)》
c++·游戏·ue5
量子炒饭大师3 天前
项目实战——C语言扫雷游戏
c语言·开发语言·游戏
开开心心就好3 天前
高效视频倍速播放插件推荐
python·学习·游戏·pdf·计算机外设·电脑·音视频
DanmF--3 天前
C#面向对象实践项目--贪吃蛇
开发语言·游戏·c#·游戏程序
Code_流苏4 天前
Python趣学篇:从零打造智能AI井字棋游戏(Python + Tkinter + Minimax算法)
python·算法·游戏·tkinter·智能井字棋·minimax算法
RedJACK~4 天前
【Go语言】Ebiten游戏库开发者文档 (v2.8.8)
开发语言·游戏·golang
Sui_Network5 天前
从公开到私密:重新思考 Web3 的数据安全
人工智能·游戏·web3·去中心化·区块链
土豆宝5 天前
AI玩游戏的一点尝试(5)—— 多样化的数字识别
人工智能·游戏
陈哥聊测试5 天前
游戏公司如何同时管好上百个游戏项目?
游戏·程序员·游戏开发