1. 问题链接:CCF 201604-2 俄罗斯方块
试题编号: | 201604-2 |
试题名称: | 俄罗斯方块 |
时间限制: | 1.0s |
内存限制: | 256.0MB |
问题描述: |
问题描述
俄罗斯方块是俄罗斯人阿列克谢·帕基特诺夫发明的一款休闲游戏。
游戏在一个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 |
2. 问题分析:
经过读题分析,本题是一道模拟题,要求模拟俄罗斯方块下落的过程,难点是数据的表示,russia_block二维数组行数比实际行数多1,表示下边界,简化了逻辑,定义一个结构体数组coordinate存储板块图案方块为1的行列坐标,定义行坐标row从1开始,其表示板块图案行坐标全体加1,板块图案在俄罗斯方块中的行列坐标为自身行坐标加上row,自身列坐标加上column-1,当第i个结构体的行坐标加1并且列坐标不变处的方块为1,则停止下落,记录下row值,然后再将俄罗斯方块对应位置的方块值赋值为1,最后遍历输出即可
3. C++语言程序实现:
#include <iostream>
using namespace std;
// declare and initiate three pseudo constants
const int ROW=15,COLUMN=10,N=4;
int russia_block[ROW+1][COLUMN],block[N][N];
// declare a struct array to store the row and column index of blocks which equal 1
struct
{
int row,column;
} coordinate[N];
int main()
{
for (int i=0; i<ROW ; i++ )
{
for (int j=0; j<COLUMN ; j++ )
{
cin>>russia_block[i][j];
}
}
for (int i=0; i<N ; i++ )
{
for (int j=0; j<N ; j++ )
{
cin>>block[i][j];
}
}
// assign 1 to all the elements of the last row to simplify the logic complexity of algorithm.
for (int i=0; i<COLUMN ; i++ )
{
russia_block[ROW][i]=1;
}
int column,k=0,row;
cin>>column;
//assign the row and column index of blocks which equal 1 to the kth struct.
for (int i=0; i<N ; i++ )
{
for (int j=0; j<N ; j++ )
{
if (block[i][j]==1)
{
coordinate[k].row=i;
coordinate[k].column=j;
k++;
}
}
}
//convert the column to the column index relative to Russia Block matrix
column--;
bool flag;
// The row starts from 1 which is the row index next only to the one relative to the block
for (row=1; row<16; row++ )
{
// reassign false to the flag which stands for the exit condition of the outer for loop.
flag=false;
for (int i=0; i<N ; i++ )
{
if (russia_block[row+coordinate[i].row][column+coordinate[i].column]==1)
{
// change the flag to true which stands for the existence of 1 below the ith block
flag=true;
}
}
if (flag)
{
break;
}
}
// let the row minus one in order to get the row index relative to Russia Block matrix
row--;
// fill the block
for (int i=0; i<N ; i++ )
{
russia_block[row+coordinate[i].row][column+coordinate[i].column]=1;
}
// print
for (int i=0;i<ROW ;i++ )
{
for (int j=0;j<COLUMN ;j++ )
{
cout<<russia_block[i][j]<<" ";
}
printf("\n");
}
return 0;
}