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