CCF CSP 201604-2.俄罗斯方块

问题描述

  俄罗斯方块是俄罗斯人阿列克谢·帕基特诺夫发明的一款休闲游戏。
  游戏在一个15行10列的方格图上进行,方格图上的每一个格子可能已经放置了方块,或者没有放置方块。每一轮,都会有一个新的由4个小方块组成的板块从方格图的上方落下,玩家可以操作板块左右移动放到合适的位置,当板块中某一个方块的下边缘与方格图上的方块上边缘重合或者达到下边界时,板块不再移动,如果此时方格图的某一行全放满了方块,则该行被消除并得分。
  在这个问题中,你需要写一个程序来模拟板块下落,你不需要处理玩家的操作,也不需要处理消行和得分。
  具体的,给定一个初始的方格图,以及一个板块的形状和它下落的初始位置,你要给出最终的方格图。

输入格式

  输入的前15行包含初始的方格图,每行包含10个数字,相邻的数字用空格分隔。如果一个数字是0,表示对应的方格中没有方块,如果数字是1,则表示初始的时候有方块。输入保证前4行中的数字都是0。
  输入的第16至第19行包含新加入的板块的形状,每行包含4个数字,组成了板块图案,同样0表示没方块,1表示有方块。输入保证板块的图案中正好包含4个方块,且4个方块是连在一起的(准确的说,4个方块是四连通的,即给定的板块是俄罗斯方块的标准板块)。
  第20行包含一个1到7之间的整数,表示板块图案最左边开始的时候是在方格图的哪一列中。注意,这里的板块图案指的是16至19行所输入的板块图案,如果板块图案的最左边一列全是0,则它的左边和实际所表示的板块的左边是不一致的(见样例)

输出格式

  输出15行,每行10个数字,相邻的数字之间用一个空格分隔,表示板块下落后的方格图。注意,你不需要处理最终的消行。

样例输入

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0
1 1 1 0 0 0 1 1 1 1
0 0 0 0 1 0 0 0 0 0
0 0 0 0
0 1 1 1
0 0 0 1
0 0 0 0
3

样例输出

0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 1 0 0
0 0 0 0 0 0 1 0 0 0
0 0 0 0 0 0 1 0 0 0
1 1 1 1 1 1 1 1 1 1
0 0 0 0 1 1 0 0 0 0


分析:

用15x10的数组matrix表示整个方格图,用4x2的数组square表示板块中4个方块所在的行和列。

执行如下循环:

循环判断板块中第i(0≤i<4)个方块,在matrix中所处位置的下一行是否存在方块,

matrix[square[i][0] + 1][square[i][1]] == 1,若存在方块,则循环结束,板块停止移动;

若板块中各方块的下一行均没有方块,则板块整体下移一行。

然后,将板块中4个方块,在matrix中所在的格子设置为1,即matrix[square[j][0]][square[j][1]] = 1,其中,0≤j<4。

最后,输出matrix即可。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <cstdio>

int main() {
// matrix存储15x10的方格图,square存储下落的板块中各方块所在的行和列
int matrix[15][10], square[4][2];
int left, data, num = 0;
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 10; j++) {
scanf("%d", &matrix[i][j]);
}
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
scanf("%d", &data);
if (data == 1) {
square[num][0] = i;
square[num++][1] = j;
}
}
}
// 板块图案最左边为第left列,由于下标从0开始,所以实际下标为left-1
scanf("%d", &left);
for (int i = 0; i < 4; i++) {
square[i][1] += left - 1;
}

bool flag = true;
while (flag) {
// 判断板块中各方块下一行是否存在方块
for (int i = 0; i < 4; i++) {
if (matrix[square[i][0] + 1][square[i][1]] == 1) {
flag = false;
break;
}
}
// 若下一行均没有方块,则板块整体下落一行
for (int i = 0; flag && i < 4; i++) {
square[i][0]++;
}
}
// 板块不再移动,将matrix中板块所在的格子,设置为1
for (int j = 0; j < 4; j++) {
matrix[square[j][0]][square[j][1]] = 1;
}
// 输出
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 10; j++) {
if (j > 0) {
printf(" ");
}
printf("%d", matrix[i][j]);
}
printf("\n");
}
return 0;
}

----------本文结束感谢您的阅读----------
坚持原创技术分享,您的支持将鼓励我继续创作!