之前在MOOC大学翁恺讲的Java进阶的期末题使用了二维数组去求解:
题目内容:
这是细胞自动机的非图形版本。细胞自动机是指在一个二维网格内,每一个网格是一个细胞。每个细胞有活和死两种状态。
初始时刻,有些细胞是活的,有些细胞是死的。自动机的每一步,根据每个细胞周围8个格子内的其他细胞的生存情况决定这个细胞下一步是否存活。具体的规则如下:
如果该细胞现在是活的,并且周围8个格子中有2或3个活着的细胞,则继续存活;如果周围8个格子中的活着的细胞数量少于2个或多于3个,则死亡;
如果该细胞现在是死的,并且周围8个格子中正好有3个活着的细胞,则细胞复活。
位于整个网格边缘和顶角的细胞,它的周围细胞可能少于8个。即越过网格的边界不再有细胞。
每个细胞的生死变化,都不会影响当前这一步周围的细胞,只会在下一步表现出来。
提示:课程中的代码与上一句描述不同。
输入格式:
首先输入两个正整数,范围为[3,102],依次表示网格的宽度和高度。
然后输入多组正整数,依次表示一个活着的细胞的网格位置,每组数字中,第一个表示行号,第二个表示列号,均从0开始编号。
最后,以“-1 -1”表示不再有活着的细胞。-1 -1不是有效的位置。
然后,以一个正整数,范围为[1,10000],表示要求细胞自动机执行的步数。
输出格式:
输出一个正整数,表示执行完毕后,剩下的活着的细胞的数量。
输入样例:
3 3
1 1 1 2 0 1 2 1
-1 -1
1
输出样例:
7
那天静下心来做了一下,花了些功夫,总得来说这个题跟http://on-img.com/chart_image/5b028e51e4b05f5d6b5feab6.png这个题有点类似,都是使用了二维数组.
分析下题干,http://on-img.com/chart_image/5b3cd291e4b0d3d5d0b77b63.png,其实难点在于判断二维数组的边角位置(突然想起了健身房经理那句话: 金角银边...)
最终还没有对代码进行重构,
import java.util.Scanner; public class CellMachine { public static void main(String[] args) { // Scanner Scanner in = new Scanner(System.in); // 矩阵大小设置 int[][] oldCellMat; int[][] cellMatrix; int width = 0; int height = 0; width = in.nextInt(); height = in.nextInt(); if (width >= 3 && height >= 3 && width <= 102 && height <= 102) { oldCellMat = new int[height][width];// 5,6的话最大下标是4,5 cellMatrix = new int[height][width]; } else { return; } // 矩阵细胞设置 int i = 0; int j = 0; while (true) { i = in.nextInt();// 行号最大为j = in.nextInt();// 列号最大为 if(i==-1 && j==-1) { break; }else { if (i >= 0 && j >= 0 && i < height && j < width) { if (cellMatrix[i][j] == 1) { return; } cellMatrix[i][j] = 1; oldCellMat[i][j] = 1; }else { return; } } } int step = 0; step = in.nextInt(); while (step != 0) { for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { boolean angle = ((row == 0) && (col == 0)) || ((row == 0) && (col == (width - 1))) || ((row == (height - 1)) && (col == 0)) || ((row == (height - 1)) && (col == (width - 1))); // boolean edge = ((row == 0) && (col != 0)) || col != (width - 1)) || col == 0 // && (row != 0 || row != (height - 1)) // || row == (height - 1) && (col != 0 || col != (width - 1)) || col == (width - // 1)) // && (row != 0 || row != (height - 1)); boolean normal = row > 0 && col > 0 && row < (height - 1) && col < (width - 1); boolean edge = !(angle) && !(normal); // 如果有细胞了的话 if (cellMatrix[row][col] == 1) { // 如果是角上细胞 if (angle) { // 左上角细胞 if (row == 0 && col == 0) { int cellNumbers = cellMatrix[row][col + 1] + cellMatrix[row + 1][col] + cellMatrix[row + 1][col + 1]; if (cellNumbers == 2 || cellNumbers == 3) { // 继续存活 } else if (!(cellNumbers == 2 || cellNumbers == 3)) { System.out.println("["+row+","+col+"]"+">>细胞死亡"); oldCellMat[row][col] = 0;// 细胞死亡 } } // 右上角细胞 if (row == 0 && col == (width - 1)) { int cellNumbers = cellMatrix[row][col - 1] + cellMatrix[row + 1][col] + cellMatrix[row + 1][col - 1]; if (cellNumbers == 2 || cellNumbers == 3) { // 继续存活 } else if (!(cellNumbers == 2 || cellNumbers == 3)) { System.out.println("["+row+","+col+"]"+">>细胞死亡"); oldCellMat[row][col] = 0;// 细胞死亡 } } // 左下角细胞 if (row == (height - 1) && col == 0) { int cellNumbers = cellMatrix[row - 1][col] + cellMatrix[row][col + 1] + cellMatrix[row - 1][col + 1]; if (cellNumbers == 2 || cellNumbers == 3) { // 继续存活 } else if (!(cellNumbers == 2 || cellNumbers == 3)) { System.out.println("["+row+","+col+"]"+">>细胞死亡"); oldCellMat[row][col] = 0;// 细胞死亡 } } // 右下角细胞 if (row == (height - 1) && col == (width - 1)) { int cellNumbers = cellMatrix[row][col - 1] + cellMatrix[row - 1][col] + cellMatrix[row - 1][col - 1]; if (cellNumbers == 2 || cellNumbers == 3) { // 继续存活 } else if (!(cellNumbers == 2 || cellNumbers == 3)) { System.out.println("["+row+","+col+"]"+">>细胞死亡"); oldCellMat[row][col] = 0;// 细胞死亡 } } } // 如果是边上细胞 << else if (edge) { // 最上沿细胞 if (row == 0) { int cellNumbers = cellMatrix[row][col - 1] + cellMatrix[row][col + 1] + cellMatrix[row + 1][col - 1] + cellMatrix[row + 1][col] + cellMatrix[row + 1][col + 1]; if (cellNumbers == 2 || cellNumbers == 3) { // 继续存活 } else if (!(cellNumbers == 2 || cellNumbers == 3)) { System.out.println("["+row+","+col+"]"+">>细胞死亡"); oldCellMat[row][col] = 0;// 细胞死亡 } } // 最左沿细胞 if (col == 0) { int cellNumbers = cellMatrix[row - 1][col] + cellMatrix[row + 1][col] + cellMatrix[row - 1][col + 1] + cellMatrix[row][col + 1] + cellMatrix[row + 1][col + 1]; if (cellNumbers == 2 || cellNumbers == 3) { // 继续存活 } else if (!(cellNumbers == 2 || cellNumbers == 3)) { System.out.println("["+row+","+col+"]"+">>细胞死亡"); oldCellMat[row][col] = 0;// 细胞死亡 } } // 最下沿细胞 if (row == (height - 1)) { int cellNumbers = cellMatrix[row][col - 1] + cellMatrix[row][col + 1] + cellMatrix[row - 1][col - 1] + cellMatrix[row - 1][col] + cellMatrix[row - 1][col + 1]; if (cellNumbers == 2 || cellNumbers == 3) { // 继续存活 } else if (!(cellNumbers == 2 || cellNumbers == 3)) { System.out.println("["+row+","+col+"]"+">>细胞死亡"); oldCellMat[row][col] = 0;// 细胞死亡 } } // 最右沿细胞 if (col == (width - 1)) { int cellNumbers = cellMatrix[row - 1][col] + cellMatrix[row + 1][col] + cellMatrix[row - 1][col - 1] + cellMatrix[row][col - 1] + cellMatrix[row + 1][col - 1]; if (cellNumbers == 2 || cellNumbers == 3) { // 继续存活 } else if (!(cellNumbers == 2 || cellNumbers == 3)) { System.out.println("["+row+","+col+"]"+">>细胞死亡"); oldCellMat[row][col] = 0;// 细胞死亡 } } } // 周围有8元素的细胞 else if (normal) { int cellNumbers = cellMatrix[row - 1][col - 1] + cellMatrix[row - 1][col] + cellMatrix[row - 1][col + 1] + cellMatrix[row][col - 1] + cellMatrix[row][col + 1] + cellMatrix[row + 1][col - 1] + cellMatrix[row + 1][col] + cellMatrix[row + 1][col + 1]; if (cellNumbers == 2 || cellNumbers == 3) { // 继续存活 } else if (!(cellNumbers == 2 || cellNumbers == 3)) { System.out.println("["+row+","+col+"]"+">>细胞死亡"); oldCellMat[row][col] = 0;// 细胞死亡 } } // 当细胞为空0时进入else } else if (cellMatrix[row][col] == 0){ // 如果是角上细胞 if (angle) { // 左上角细胞 if (row == 0 && col == 0) { int cellNumbers = cellMatrix[row][col + 1] + cellMatrix[row + 1][col] + cellMatrix[row + 1][col + 1]; if (cellNumbers == 3) { System.out.println("["+row+","+col+"]"+">>细胞再生"); oldCellMat[row][col] = 1;// 细胞再生 } else { // 保持死亡 } } // 右上角细胞 if (row == 0 && col == (width - 1)) { int cellNumbers = cellMatrix[row][col - 1] + cellMatrix[row + 1][col] + cellMatrix[row + 1][col - 1]; if (cellNumbers == 3) { System.out.println("["+row+","+col+"]"+">>细胞再生"); oldCellMat[row][col] = 1;// 细胞再生 } else { // 保持死亡 } } // 左下角细胞 if (row == (height - 1) && col == 0) { int cellNumbers = cellMatrix[row - 1][col] + cellMatrix[row][col + 1] + cellMatrix[row - 1][col + 1]; if (cellNumbers == 3) { System.out.println("["+row+","+col+"]"+">>细胞再生"); oldCellMat[row][col] = 1;// 细胞再生 } else { // 保持死亡 } } // 右下角细胞 if (row == (height - 1) && col == (width - 1)) { int cellNumbers = cellMatrix[row][col - 1] + cellMatrix[row - 1][col] + cellMatrix[row - 1][col - 1]; if (cellNumbers == 3) { System.out.println("["+row+","+col+"]"+">>细胞再生"); oldCellMat[row][col] = 1;// 细胞再生 } else { // 保持死亡 } } } // 如果是边上细胞 else if (edge) { // 最上沿细胞 if (row == 0) { int cellNumbers = cellMatrix[row][col - 1] + cellMatrix[row][col + 1] + cellMatrix[row + 1][col - 1] + cellMatrix[row + 1][col] + cellMatrix[row + 1][col + 1]; if (cellNumbers == 3) { System.out.println("["+row+","+col+"]"+">>细胞再生"); oldCellMat[row][col] = 1;// 细胞再生 } else { // 保持死亡 } } // 最左沿细胞 if (col == 0) { int cellNumbers = cellMatrix[row - 1][col] + cellMatrix[row + 1][col] + cellMatrix[row - 1][col + 1] + cellMatrix[row][col + 1] + cellMatrix[row + 1][col + 1]; if (cellNumbers == 3) { System.out.println("["+row+","+col+"]"+">>细胞再生"); oldCellMat[row][col] = 1;// 细胞再生 } else { // 保持死亡 } } // 最下沿细胞 if (row == (height - 1)) { int cellNumbers = cellMatrix[row][col - 1] + cellMatrix[row][col + 1] + cellMatrix[row - 1][col - 1] + cellMatrix[row - 1][col] + cellMatrix[row - 1][col + 1]; if (cellNumbers == 3) { System.out.println("["+row+","+col+"]"+">>细胞再生"); oldCellMat[row][col] = 1;// 细胞再生 } else { // 保持死亡 } } // 最右沿细胞 if (col == (width - 1)) { int cellNumbers = cellMatrix[row - 1][col] + cellMatrix[row + 1][col] + cellMatrix[row - 1][col - 1] + cellMatrix[row][col - 1] + cellMatrix[row + 1][col - 1]; if (cellNumbers == 3) { System.out.println("["+row+","+col+"]"+">>细胞再生"); oldCellMat[row][col] = 1;// 细胞再生 } else { // 保持死亡 } } } // 周围有8元素的细胞 else if (normal) { int cellNumbers = cellMatrix[row - 1][col - 1] + cellMatrix[row - 1][col] + cellMatrix[row - 1][col + 1] + cellMatrix[row][col - 1] + cellMatrix[row][col + 1] + cellMatrix[row + 1][col - 1] + cellMatrix[row + 1][col] + cellMatrix[row + 1][col + 1]; if (cellNumbers == 3) { System.out.println("["+row+","+col+"]"+">>细胞再生"); oldCellMat[row][col] = 1;// 细胞再生 } else { // 保持死亡 } } } // else_end cellMatrix[row][col] != 1 } // inner_for_end } // for_end for (int w = 0; w < height; w++) { for (int v = 0; v < width; v++) { cellMatrix[w][v] = oldCellMat[w][v]; } } step--; } // while_ed int count = 0; for (int m = 0; m < height; m++) { for (int n = 0; n < width; n++) { if (cellMatrix[m][n] == 1) { count++; } } } System.out.println(">>最终存活细胞数量:"+count+"<<"); // System.out.println(count); } }
最近越发得留意和想起网上的那句话:写代码是个细致活,是个手艺.不单纯是个技术.
钻研有时候是很痛苦的,那是因为书看得少了.
再把心平复下来,好好看看算法那本书吧,以及其他的在图灵图书分享的那些算法书籍.算法也是编程的一个重要内容啊
在CW上做的java题,还有几道对我而言难度有些大,而手头还要做两个web项目.
时间如果再充沛些就好了!