您的位置:首页 > 编程语言 > Python开发

python ccf题解 201604-2 俄罗斯方块

2018-09-02 17:51 197 查看

问题描述

试题编号: 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

解决问题思路是模拟板块下降的过程,若有碰撞则发生碰撞上一行就是最终确定的位置,若板块与方格图某个位置都为1即为碰撞了产生重叠,这个位置两项加起来为2,判断板块与方格图每项分别加起来是否有2就能确认是否碰撞。

代码

[code]#俄罗斯方块
tmap = []#存储(15+3)行10列的方格图信息

#读取输入
for i in range(15):
tmap.append(list(map(int,input().split())))#从标准输入读取每行数据存入tmap
for i in range(3):
tmap.append([1]*10)#再存入3行都是1的方格图信息,目的是方便下面循环,保证4行板块第一行对应15行方格图最后一行时行数最大为(15+4-1)不会越界

shape = []#存储板块信息
for i in range(4):
shape.append(list(map(int,input().split())))#读入板块形状数据
x = int(input())#读入板块起始列

#板块数据根据起始列从4行4列扩展到4行10列
for i in range(4):
shape[i] = [0]*(x-1) + shape[i] + [0]*(10-4-(x-1))
#每行左边0的个数(x-1),右边0的个数(10-4-(x-1))。[0]*x意为列表[0,0,...]有x个0

right = 0#板块第一行最终落到的方格图行数
find = False#标记是否找到位置

#判断板块位置
for i in range(15):#遍历方格图所有行
#从第i行开始检测方格图与板块是否已经碰撞
for j in range(4):#遍历板块每一行
newline = [a+b for a,b in zip(tmap[i+j],shape[j])]#将一行的方格图每项数据与板块每项数据相加生成新行
if(2 in newline):#如果新行里出现了2,说明存在有位置方格图与板块对应数据都为1,即产生了碰撞
right = i-1#第一次出现碰撞的上一行就是板块第一行最终落到的位置
find = True#找到了
break#退出里层循环
if(i == 14):
right=14#如果搜索到了最后一行,则直接确定行数
if(find):#找到了位置就退出外层循环,没找到就让板块下降一格继续循环
break

#拼接方格图与板块生成最终方格图数据
for j in range(4):
tmap[right+j]= [a+b for a,b in zip(tmap[right+j],shape[j])]#相当于将板块信息置入方格图
#zip()函数将两个列表各项一一对应,for a,b in zip(...)遍历两个列表的每项分别为a,b ;[a+b for a,b in ...]将每项加起来生成新的列表

#输出数据
for i in range(15):
print(" ".join(map(str,tmap[i])))#map(str,tmap[i])将tmap里所有的int数据转换成str字符串用于拼接," ".join(...)将字符串列表每项中间加空格生成一个长的字符串

list(map(int,input().split()))读取一行以空格分隔的数据转换为列表:

    input().split()将一行根据空格分隔为字符串列表,map(int,input().split())将字符串列表每项str字符串转化为int型生成map对象,最后list()将map对象转换为list列表,此时list中每项都是int型数据

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: