Game of Life
思路:其实这题不难,关键是状态的储存。我设置了map1和map2用于储存当前状态和下一状态,在函数check(见以下代码)中,当map1储存当前状态时,map2就是下一状态,反之亦然。另外一个关键点是怎么判断3×3区域内黑多还是白多,我设置了一个值BLACK = 5*'b'+4*'w',这是黑多于白的临界情况,由于' b ' < ' w ',所以当3×3区域内所有字符的ASC2码相加的结果大于BLACK时,就是白多,反之黑多。
AC Code:
#include <stdio.h> #include <string.h> #define BLACK 5*'b'+4*'w' char map1[513][513], map2[513][513]; int flag, b; int m, t; void check(int i, int j) { if(flag > 0) { if(map1[i-1][j-1] + map1[i][j-1] + map1[i+1][j-1] + map1[i-1][j] + map1[i+1][j] + map1[i-1][j+1] + map1[i][j+1] + map1[i+1][j+1] + map1[i][j] > BLACK) { /*1.当且仅当当前状态为b时才执行b--。2.注意map2[i][j] = 'w'不能放在if中 因为无论if中的条件是否为真,此指令都需要执行,因为map1[i][j] == 'w'(if 判断条件为假)时不意味着map2[i][j] == 'w'。如果不理解可以把程序后附上的 例子执行一次*/ if(map1[i][j] == 'b') b--; map2[i][j] = 'w'; } else { if(map1[i][j] == 'w') b++; map2[i][j] = 'b'; } } else { if(map2[i-1][j-1] + map2[i][j-1] + map2[i+1][j-1] + map2[i-1][j] + map2[i+1][j] + map2[i-1][j+1] + map2[i][j+1] + map2[i+1][j+1] + map2[i][j] > BLACK) { if(map2[i][j] == 'b') b--; map1[i][j] = 'w'; } else { if(map2[i][j] == 'w') b++; map1[i][j] = 'b'; } } } int main() { int n; scanf("%d", &n); while(n--) { scanf("%d%d", &m, &t); for(int i = 0; i < m; i++) { scanf("%s", map1[i]); strcpy(map2[i], map1[i]); } //for(int i=0; i<m; i++) puts(map2[i]); flag = 1; b = 0; for(int i = 0; i < m; i++) { for(int j = 0; j < m; j++) if(map1[i][j] == 'b') b++; } //printf("%d %d", b, w); while(t--) { for(int i = 1; i < m-1; i++) { for(int j = 1; j< m-1; j++) check(i, j); } flag = -flag; } //for(int i = 0; i < m; i++) puts(map2[i]); printf("%d %d\n", b, m * m - b); } return 0; }
3 3
www
wdw
www