欢迎来到就算过了一载春秋的博客

不管过了几载春秋,我还是会偶尔想起。

CCF-CSP201604-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

 

看着挺复杂,其实模拟一下过程即可。

掉下来的板块首先是第4行落在方格图的第1行,然后是第3行落在方格图的第1行(第4行落在方格图的第2行),依次类推。

当板块中某一个方块的下边缘与方格图上的方块上边缘重合或者达到下边界时,板块不再移动

板块的第i行位于方格图的第j行时,由数学关系知:

板块的第1行位于方格图的i-j+1行,板块的第2行位于方格图的i-j+2行,板块的第3行位于方格图的i-j+3行,板块的第4行位于方格图的i-j+4行

AC代码:

 1 #include<iostream>
 2 #include<sstream>
 3 #include<algorithm>
 4 #include<string>
 5 #include<cstring>
 6 #include<iomanip>
 7 #include<vector>
 8 #include<cmath>
 9 #include<ctime>
10 #include<stack>
11 #include<queue>
12 using namespace std;
13 int main()
14 {
15     bool map[20][12],block[5][5];
16     int start;
17     memset(map,0,sizeof(0)); 
18     for(int i=1;i<=15;i++)
19         for(int j=1;j<=10;j++)
20             cin>>map[i][j];
21     for(int i=1;i<=4;i++)
22         for(int j=1;j<=4;j++)
23             cin>>block[i][j];
24     cin>>start;
25     
26     bool flag=0;
27     for(int i=1;i<=15&&!flag;i++)    
28     {
29         for(int j=4;j>=1&&!flag;j--)//block的第j行下落到map的第i行 
30         {
31                 int p=start,q=1;
32             for(;p<start+4&&q<=4&&!flag;p++,q++)//map从第start列开始,block从第1列开始 
33             {
34                 //当板块中某一个方块的下边缘与方格图上的方块上边缘重合
35                 if(map[i+1][p]&&block[j][q]) flag=1;
36                 //块中某一个方块的下边缘达到下边界时
37                 else if(i==15&&block[j][q])  flag=1;
38             }    
39             
40             if(flag)//填充方块 
41             { 
42                         int m=i-j+1,n=1;
43                 for(;m<i-j+1+4&&n<=4;m++,n++)
44                 {
45                     for(p=start,q=1;p<start+4&&q<=4;p++,q++)
46                     if(block[n][q]&&!map[m][p]) map[m][p]=1;
47                 }
48             }
49         } 
50     }  
51     
52     for(int i=1;i<=15;i++)//输出,不需要消行 
53     {
54         for(int j=1;j<=10;j++)
55         cout<<map[i][j]<<' ';
56         cout<<endl;
57     }
58 }
59  
View Code

posted on 2018-09-14 18:23  就算过了一载春秋  阅读(201)  评论(0)    收藏  举报

导航