消除游戏是众多游戏中的一种,貌似十分流行。其内部实现也许是程序员们所感兴趣的。
问题描述:可以输入多组测试用例,每组测试用例首先输入正整数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("\n");
}
}
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