试题编号: | 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 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 1 0 00 0 0 0 0 0 1 0 0 00 0 0 0 0 0 1 0 0 01 1 1 0 0 0 1 1 1 10 0 0 0 1 0 0 0 0 00 0 0 00 1 1 10 0 0 10 0 0 03样例输出0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 1 0 00 0 0 0 0 0 1 0 0 00 0 0 0 0 0 1 0 0 01 1 1 1 1 1 1 1 1 10 0 0 0 1 1 0 0 0 0 |
问题分析:关键是如何处理下落方块下落的过程。方块下落中遇到阻碍时应该怎么解决?在方块下落中,从图的第五行开始,从方块的最下一行开始到第一行依次判断其是否会与此行发生碰撞。若发生碰撞,则将方块安放在发生碰撞的上一行,同时要注意下落方块的那一行与图发生了碰撞,以便安放在正确的位置。若没有发生碰撞,则判断图的下一行是否会发生碰撞,同时继续判断下落方块的上一行和图的本行是否发生碰撞,直到判断完下落方块的所有行。
测试用例:
0 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 01 1 1 1 0 1 1 1 1 10 0 0 0 1 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 1 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 0 0 0 0 0 0 00 0 0 00 1 1 10 0 1 00 0 1 03
代码:
#include <iostream>#include <stdio.h>using namespace std;/* run this PRogram using the console pauser or add your own getch, system("pause") or input loop */int t[17][11];int block[5][5];int n=15,m=10;void load(int row,int col,int s){//0-s行 for(int i=0,p=row-s;i<=s;i++,p++){for(int j=0,q=col;j<4;j++,q++){if(block[i][j] == 1)t[p][q]=block[i][j];}}//s-3行for(int i=s+1,p=row+1;i<4;i++,p++){for(int j=0,q=col;j<4;j++,q++){if(block[i][j] == 1){t[p][q]=block[i][j];}}} }//void scan(int row,int col,int s)//{// //从图的row行col列开始针对下落方块的第s行扫描// for(int i=row;i<=n;i++)// {// for(int j=col,h=0;j<col+4;j++,h++)// {// if(t[i][j] == 1 && block[s][h]==1)// {// //方块和图内的方块产生碰撞 // load(i-1,col,s); //产生碰撞则将方块下落安置在碰撞产生的上一行// //即s行放在i-1行 // return; // } // }// } // //若s行在i<n的所有行中都没有发生碰撞 那么s行就不可能和任何行发生碰撞 // //因此转入对s行的上一行的判断 // scan(row,col,s-1);//// if(s == 0)//// {//// //若下落方块的最上一行也没有发生碰撞 则方块直接下落到最下一层 //// load(n-1,col,3);//// }// return; //} void scan(int row,int col){//从图的row行col列开始针对下落方块的第s行扫描for(int i=3;i>=0;i--) //下落方块从第四行到第一行开始扫描 {for(int j=col,h=0;j<col+4;j++,h++){if(t[row][j]==1 && block[i][h] == 1){load(row-1,col,i);return;}}scan(row+1,col); }scan(row+1,col);}int main(int argc, char *argv[]) {//读入图 //while(true){ for(int i=0;i<n;i++){for(int j=0;j<m;j++){scanf("%d",&t[i][j]);}} for(int i=0;i<m;i++){t[15][i]=1;} //读入下落块 for(int i=0;i<4;i++){for(int j=0;j<4;j++){scanf("%d",&block[i][j]);}} int p;//初始下落位置 scanf("%d",&p);scan(4,p-1);for(int i=0;i<n;i++){int j;for(j=0;j<m-1;j++){printf("%d ",t[i][j]);}printf("%d",t[i][j]);printf("/n");}} return 0;}
新闻热点
疑难解答