试题编号: | 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 |
#include<iostream>
using namespace std;
int main()
{
int ranks[15][10];
int picture[4][4];
int start;
int boder1[4]={14,14,14,14},boder2[4]={-10,-10,-10,-10};
for(int i=0;i<15;i++)
for(int j=0;j<10;j++)
cin>>ranks[i][j];
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
cin>>picture[i][j];
cin>>start;
start=start-1;
for(int i=start;i<start+4;i++) //原始数组的上界
for(int j=0;j<15;j++)
if(ranks[j][i]==1)
{
boder1[i-start]=j-1;
break;
}
for(int i=0;i<4;i++) //输入数组的下界
for(int j=0;j<4;j++)
if(picture[j][i]==1)
boder2[i]=j;
int min(20);
int t(0);
for(int i=0;i<4;i++) //对比得最小距离
if(boder1[i]-boder2[i]<min)
{
min=boder1[i]-boder2[i];
t=i;
}
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
if(picture[i][j]==1)
ranks[boder1[t]-boder2[t]+i][start+j]=1;
for(int i=0;i<15;i++)
{
for(int j=0;j<10;j++)
{
if(j==0)
cout<<ranks[i][j];
else
cout<<" "<<ranks[i][j];
}
cout<<endl;
}
return 0;
}
下面是某位帅气的学长写的
#include <iostream>
using namespace std;
int main()
{
int gameArea[15][10];//游戏棋盘
int randCube[4][4];//随机方块
int realCube[4][2];//真实游戏中每次随机方块出现的位置
int place;
int temp,i,j,k;
//解题思路:将整个游戏棋盘中已经有方块的部分设为值2,保存产生的四个随机方块的横纵坐标,模拟游戏过程,当该方块向下运动时,若未触到底部,则继续向下运动。
//若触到底部,则保存此时的随机方块位置,并将对应棋盘的位置设置为值2,得到的棋盘即为结果,只需要将值2都改为值1,输出即可。
//注意:为什么要讲棋盘上已有方块的位置设为值2而不是1,因为在判断方块是否触底时,是判断四个方块下面的位置的值是否为2,如果是1,则判断过程可能有错误。
for(i = 0;i<15;i++)
for(j = 0;j<10;j++)
{
cin>>gameArea[i][j];
/*if(gameArea[i][j])
gameArea[i][j] = 2;*/
}
for(i = 0;i<4;i++)
for(j = 0;j<4;j++)
cin>>randCube[i][j];
cin>>place;//输入部分
k = 0;
for(i = 0;i<4;i++)
for(j = 0;j<4;j++)
{
if(randCube[i][j])
{
realCube[k][0] = j+place-1;
realCube[k][1] = i;
k++;
}
}//保存初始四个随机方块的横纵坐标
temp = 0;
while(1)
{
for(i = 0;i<4;i++)
{
k = gameArea[realCube[i][1]+1][realCube[i][0]];
if(k == 1 || realCube[i][1] == 14)//如果某个方块触底
temp = 1;
}
if(temp == 0)//如果方块都没有触底,则继续运动
{
for(i = 0;i<4;i++)
realCube[i][1]++;
}
else
break;
}
for(i = 0;i<4;i++)
gameArea[realCube[i][1]][realCube[i][0]] = 1;//将触底时随机方块在棋盘上的位置设置为2
/*for(i = 0;i<15;i++)
for(j = 0;j<10;j++)
if(gameArea[i][j])
gameArea[i][j] = 1;//还原棋盘为标准输出 */
for(i = 0;i<15;i++)
{
for(j = 0;j<9;j++)
cout<<gameArea[i][j]<<" ";
cout<<gameArea[i][9]<<endl;//输出结果
}
return 0;
}