消除游戏是众多游戏中的一种,貌似十分流行。其内部实现也许是程序员们所感兴趣的。
问题描述:可以输入多组测试用例,每组测试用例首先输入正整数m和n,分别为矩阵的行和列数,m,n≤1000,然后输入m行n列的正整数数据。将m×n矩阵中行或列连续三个元素同值的变为0。当m和n同时为0时程序结束。
问题分析:有各种各样的实现方法。这里采用一种不使用另外存储的做法,需要消除的元素暂时将其值变为负值,等行和列都标记之后,再统一消除(置值)为0。
程序说明:封装了若干个功能函数来实现,使得程序逻辑变得简洁。
AC的C语言程序如下:
/* I00033 消除游戏 */ #include <stdio.h> #include <stdlib.h> #define MAXN 1000 int grid[MAXN+1][MAXN+1]; void output_result(int g[][MAXN+1], int m, int n) { int i, j; for(i=0; i<m; i++) { for(j=0; j<n; j++) printf("%4d", g[i][j]); printf(" "); } } void cleargame(int g[][MAXN+1], int m, int n) { int count, last, i, j; /* 行消除 */ for(i=0; i<m; i++) { count = 0; last = g[i][0]; for(j=1; j<n; j++) { if(abs(g[i][j]) != abs(last)) { count = 0; last = g[i][j]; } else if(++count >= 3) { g[i][j] = -g[i][j]; if(g[i][j-1] > 0) { g[i][j-1] = -g[i][j-1]; g[i][j-2] = -g[i][j-2]; } } else count++; } } /* 列消除 */ for(i=0; i<n; i++) { count = 0; last = g[0][i]; for(j=1; j<m; j++) { if(abs(g[j][i]) != abs(last)) { count = 0; last = g[j][i]; } else if(++count >= 3) { g[j][i] = -abs(g[j][i]); g[j-1][i] = -abs(g[j-1][i]); g[j-2][i] = -abs(g[j-2][i]); } else count++; } } } void reset(int g[][MAXN+1], int m, int n) { int i, j; for(i=0; i<m; i++) for(j=0; j<n; j++) if(g[i][j] < 0) g[i][j] = 0; } int main(void) { int m, n, i, j; while(scanf("%d%d", &m, &n) != EOF && m+n) { for(i=0; i<m; i++) for(j=0; j<n; j++) scanf("%d", &grid[i][j]); cleargame(grid, m, n); reset(grid, m, n); output_result(grid, m, n); } return 0; } /* 测试数据 5 5 3 3 3 3 1 2 3 4 4 4 2 1 1 1 4 2 3 4 5 4 2 3 4 4 4 4 5 3 3 3 6 1 2 5 4 4 4 1 1 1 2 4 2 3 4 4 4 0 0 */
运行实例如下:
5 5
3 3 3 3 1
2 3 4 4 4
2 1 1 1 4
2 3 4 5 4
2 3 4 4 4
0 0 0 0 1
0 3 0 0 0
0 0 0 0 0
0 3 4 5 0
0 3 0 0 0
4 5
3 3 3 6 1
2 5 4 4 4
1 1 1 2 4
2 3 4 4 4
0 0 0 6 1
2 5 0 0 0
0 0 0 2 0
2 3 0 0 0
0 0