问题链接:CCF NOI1057 石头剪刀布。
时间限制: 1000 ms 空间限制: 262144 KB
题目描述
Bart的妹妹Lisa在一个二维矩阵上创造了新的文明。矩阵上每个位置被三种生命形式之一占据:石头,剪刀,布。每天,上下左右相邻的不同生命形式将会发生战斗。在战斗中,石头永远胜剪刀,剪刀永远胜布,布永远胜石头。每一天结束之后,败者的领地将被胜者占领。
你的工作是计算出n天之后矩阵的占据情况。
输入
第一行包含三个正整数r,c,n,分别表示矩阵的行数、列数以及天数。每个整数均不超过100。
接下来r行,每行c个字符,描述矩阵初始时被占据的情况。每个位置上的字符只能是R,S,P三者之一,分别代表石头,剪刀,布。相邻字符之间无空格。
输出
输出n天之后的矩阵占据情况。每个位置上的字符只能是R,S,P三者之一,相邻字符之间无空格。
样例输入
3 3 1
RRR
RSR
RRR
样例输出
RRR
RRR
RRR
问题分析
这是一个模拟题,直接模拟计算即可。
需要用一些程序技巧,使得程序代码简洁一些。
程序说明
上下左右的坐标放在数组around[]中,程序的处理就可以用循环来控制。
定义二维数组用于存储二维矩阵,周围多出一圈,可以省去数组下标的越界判定。
函数doit()封装的功能是计算每一天过后矩阵的占据情况。
参考链接:(略)。
100分通过的C语言程序:
#include <stdio.h>
#include <string.h>
struct _around {
int drow;
int dcol;
} around[] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
#define AN 4
#define N 100
char a[N+2][N+2], b[N+2][N+2];
void doit(char x[][N+2], char y[][N+2], int r, int c)
{
int i, j, k;
for(i=1; i<=r; i++)
for(j=1; j<=c; j++)
if(x[i][j] == 'R') {
for(k=0; k<AN; k++)
if(x[i + around[k].drow][j + around[k].dcol] == 'S')
y[i + around[k].drow][j + around[k].dcol] = 'R';
} else if(x[i][j] == 'S') {
for(k=0; k<AN; k++)
if(x[i + around[k].drow][j + around[k].dcol] == 'P')
y[i + around[k].drow][j + around[k].dcol] = 'S';
} else if(x[i][j] == 'P') {
for(k=0; k<AN; k++)
if(x[i + around[k].drow][j + around[k].dcol] == 'R')
y[i + around[k].drow][j + around[k].dcol] = 'P';
}
}
int main(void)
{
int r, c, n, i, j, k;
memset(a, 0, sizeof(a));
scanf("%d%d%d", &r, &c, &n);
for(i=1; i<=r; i++)
scanf("%s", a[i]+1);
memcpy(b, a, sizeof(a));
for(k=1; k<=n; k++)
if(k & 1) {
doit(a, b, r, c);
memcpy(a, b, sizeof(a));
} else {
doit(b, a, r, c);
memcpy(b, a, sizeof(a));
}
for(i=1; i<=r; i++) {
for(j=1; j<=c; j++)
printf("%c", a[i][j]);
printf("\n");
}
return 0;
}