根据百度百科,生命游戏,简称为生命,是英国数学家约翰·何顿·康威在1970年发明的细胞自动机。
给定一个包含 m × n 个格子的面板,每一个格子都可以看成是一个细胞。每个细胞具有一个初始状态 live(1)即为活细胞, 或 dead(0)即为死细胞。每个细胞与其八个相邻位置(水平,垂直,对角线)的细胞都遵循以下四条生存定律:
1. 如果活细胞周围八个位置的活细胞数少于两个,则该位置活细胞死亡;
2. 如果活细胞周围八个位置有两个或三个活细胞,则该位置活细胞仍然存活;
3. 如果活细胞周围八个位置有超过三个活细胞,则该位置活细胞死亡;
4. 如果死细胞周围正好有三个活细胞,则该位置死细胞复活;
根据当前状态,写一个函数来计算面板上细胞的下一个(一次更新后的)状态。
进阶:
- 你可以使用原地算法解题吗?请记住,面板上所有格子需要同时被更新:你不能先更新某些格子,然后使用它们的更新后的值更新其他格子。
- 在此题中,我们使用二维数组来表示面板。原则上,面板是无限的,但当活细胞侵占了面板边界时会造成问题。你将如何解决这些问题?
细节:
当一个格子更新后该格子状态可能改变,所以再声明一个vector二维数组存放格子的信息,运行完毕后把这个数组赋值给board即可。
思路:
枚举每个格子,通过条件判断这个细胞是死还是活,判断可通过一个二维数组Walk遍历周围8个格子
#include <iostream> #include <vector> #include <list> using namespace std; int m,n;//m行,n列 int Walk[][2]= {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}}; //8个方向 int IsLegal(int x,int y) { if(x>=0&&y>=0&&x<m&&y<n) return 1; return 0; } int Sum(int x,int y,vector<vector<int > >&tepp) //统计坐标为x y的细胞的 周围8个格子中的活细胞数,这里的tepp也就是board,也可以放在类里去掉这个参数直接调用 { int tepx,tepy; int sum=0; for(int i=0; i<8; i++) { tepx=x+Walk[i][0]; tepy=y+Walk[i][1]; if(IsLegal(tepx,tepy)==1&&tepp[tepx][tepy]==1)//如果该格子坐标合法且为活细胞则统计数+1 { ++sum; } } return sum; } class Solution { public: void gameOfLife(vector<vector<int > >& board) { m=board.size(); int i,j; if(m!=0) n=board[0].size(); else m=0; vector<vector<int > > Tep;//记录下面板的状态 防止本次更新对本次遍历的影响 Tep.resize(m); for(i=0; i<n; i++) Tep[i].resize(n); for(i=0; i<m; i++) { for(j=0; j<n; j++) { int p=Sum(i,j,board);//根据周围八个格子状态判断坐标为i,j的格子接下来的状态 if(board[i][j]==0&&p==3) { Tep[i][j]=1; } else if(board[i][j]==1) { if(p<2||p>3) Tep[i][j]=0; else if(p==2||p==3)Tep[i][j]=1; else Tep[i][j]=0; } else Tep[i][j]=0; } } board=Tep; } }; int main() { vector<vector<int > > ss; vector<int > klc; klc.push_back(0); klc.push_back(0); ss.push_back(klc); Solution ans; ans.gameOfLife(ss); return 0; }