ccf题库中2016年4月2日俄罗斯方块问题
题目如下:
问题描述
俄罗斯方块是俄罗斯人阿列克谢·帕基特诺夫发明的一款休闲游戏。
游戏在一个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个数字,相邻的数字之间用一个空格分隔,表示板块下落后的方格图。注意,你不需要处理最终的消行。
样例输入 样例输出
网上一般是模拟方块下落的过程,这种方法简洁,易于理解,代码如下:
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
struct Node{
int x;
int y;
};
int main()
{
int s[][];
Node t[];
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
cin>>s[i][j];
}
}
int count=;
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
int temp;
cin>>temp;
if(temp==)
{
t[count].x=i;
t[count].y=j;
count++;
}
}
}
int col;
cin>>col;
if(col+>=)
{
return ;
}else{
for(int i=;i<;i++)
{
t[i].y+=col-;
}
}
int flag=;
while()
{
for(int i=;i<;i++)
{
if(s[t[i].x][t[i].y])
{
flag=;
break;
}
}
if(flag)
{
break;
}else{
for(int i=;i<;i++)
{
t[i].x++;
}
}
}
if(flag==)
{
for(int i=;i<;i++)
{
s[t[i].x-][t[i].y]=;
}
}
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
cout<<s[i][j]<<" ";
}
cout<<endl;
}
return ;
}
我刚开始的想法是,为什么不从最后一行开始,那样不是更快吗?后来我发现这个想法不对,从下往上找,要一直遍历到第0行,这样的计算量特别大。
下面,我说说自己的想法:先通过遍历找到对应方块在大矩阵中的最下面一行,然后以这个行数为标准来将图形填充到大的矩阵中。详细说明,在代码中。
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
#include<algorithm>
using namespace std;
struct Node{
int x;
int y;
int row;
};
int cmp(Node x,Node y)
{
return x.x>y.x;
}
int main()
{
int s[][];
Node t[];
Node temp[];//在这里t用作遍历时的数组,temp主要是方便赋值
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
cin>>s[i][j];
}
}
int count=;
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
int tem;
cin>>tem;
if(tem==)
{
t[count].x=i;
t[count].y=j;
t[count].row=;
temp[count].x=i;
temp[count].y=j;
temp[count].row=;
count++;
}
}
}
int col;
cin>>col;
if(col+>=)
{
return ;
}else{
for(int i=;i<;i++)
{
t[i].y+=col-;
temp[i].y+=col-;
}
}
sort(t,t+,cmp);
sort(temp,temp+,cmp);
//-----------------找出最下面的一行-------------------------
int row,real_row;
for(real_row=;real_row>=;real_row--){//一行一行的遍历,从最底层开始。
row=real_row;
int flag;
for(;row>=;row--)//将从最低行一直遍历到第0行
{
int temp_row=row;
flag=;
for(int j=;j<;j++)
{
if(j==){
if(temp_row<){
break;
}
if(s[temp_row][t[j].y]==){
flag=;//标记失败
break;
}else{
temp_row=temp_row-t[j].x+t[j+].x;
}
}else{
if(temp_row<){
break;
}
if(s[temp_row][t[j].y]==){
flag=;//标记失败
break;
}else{
if(j<=){
temp_row=temp_row-t[j].x+t[j+].x;
}
}
}
}
if(flag==){//出现失败后没有必要在遍历了,跳出循环,对下一个real_row进行从real_row到0的遍历
break;
}
}
if(flag==){//说明出现了满足情况的行数,停止执行。
break;
}
}
//--------------重新赋值--------------------
// cout<<"最终行数为:"<<real_row<<endl;
for(int i=;i<;i++)
{
if(i==){
temp[i].x=real_row;
real_row=real_row-t[].x+t[].x;
}else{
temp[i].x=real_row;
if(i<=){
real_row=real_row-t[i].x+t[i+].x;//利用小矩阵中函数差,来确定对应的大矩阵中的行数,例如,t[0]在小矩阵中是第二行,t[1]在小矩阵中是第一行,t[0]在大矩阵中是第13行,那么t[1]应该是13-2+1=12行
}
}
s[temp[i].x][temp[i].y]=;
}
//--------------输出结果--------------------
for(int i=;i<;i++)
{
for(int j=;j<;j++)
{
cout<<s[i][j]<<" ";
}
cout<<endl;
}
return ;
}
ccf题库中2016年4月2日俄罗斯方块问题的更多相关文章
- ccf题库中2015年12月2号消除类游戏
题目如下: 问题描述 消除类游戏是深受大众欢迎的一种游戏,游戏在一个包含有n行m列的游戏棋盘上进行,棋盘的每一行每一列的方格上放着一个有颜色的棋子,当一行或一列上有连续三个或更多的相同颜色的棋子时,这 ...
- c++中变量声明和变量定义的区别。2016年12月6日
整个流程: 1.程序告诉cpu,程序将要使用一个变量.(暂时不一定用到,先说一下.) 2.程序告诉CPU,程序现在就要使用一个变量.(现在就用) 3.cpu按照这个变量的类型,把内存划分出几个单位(b ...
- 我的Python成长之路---第八天---Python基础(24)---2016年3月5日(晴)
多线程编程 什么是多线程,线程是操作系统能够进行运算调度的最小单位.他包含在进程之中,是进程中的实际运作单位.线程是进程中一个单顺序的空值六,一个进程可以并发多个线程,每个线程可以并行处理不同的任务. ...
- Git学习(二)(2015年11月18日)(2016年1月29日)
2015年11月18日Git学习: .Shell 删除文件夹及其所有文件 rd/s/q 文件目录 ---------------当前为先创建本地Git库后与网上Git服务器关联------------ ...
- 2016年2月16日开始,每天一篇,记录学习心得,【基本技能篇】>>开篇《如何阅读一本书——心得》
如何阅读一本书——心得 ——2016年2月12日 要达到阅读的所有目的,就必须在阅读不同书籍的时候,运用适当的不同速度.读的太快或太慢,都一无所获. 四个阅读层次:①基础阅读,具有基本阅读的能力,包括 ...
- Python array,list,dataframe索引切片操作 2016年07月19日——智浪文档
array,list,dataframe索引切片操作 2016年07月19日——智浪文档 list,一维,二维array,datafrme,loc.iloc.ix的简单探讨 Numpy数组的索引和切片 ...
- Yoshua Bengio 2016年5月11日在Twitter Boston的演讲PPT
Yoshua Bengio最新演讲:Attention 让深度学习取得巨大成功(46ppt) Yoshua Bengio,电脑科学家,毕业于麦吉尔大学,在MIT和AT&T贝尔实验室做过博士后研 ...
- 2016年11月2日 星期三 --出埃及记 Exodus 19:18
2016年11月2日 星期三 --出埃及记 Exodus 19:18 Mount Sinai was covered with smoke, because the LORD descended on ...
- 2016年10月31日 星期一 --出埃及记 Exodus 19:16
2016年10月31日 星期一 --出埃及记 Exodus 19:16 On the morning of the third day there was thunder and lightning, ...
随机推荐
- Linux 定时任务 crontab 和 Systemd Timer
一.说说八卦 说到定时任务,我们常用的就是 crond 服务,但是我们不知道还有另外一种定时方式,那就是 systemd,我们常用 systemd 来管理我们的服务,但是我们却不知道,我们还可以通 ...
- 简明awk教程(Simple awk tutorial)
整理翻译.原文地址:http://www.hcs.harvard.edu/~dholland/computers/awk.html 简明awk教程 为什么选awk? awk小巧.快速.简单.awk语言 ...
- lightswitch Grid 控件添加 CheckBox 多选
ACTIVATING MULTI SELECTION WITH CHECKBOXES IN A LIGHTSWITCH GRID WITH A ONE-LINER 2013/04/02 · by pa ...
- [NOI 2017]蔬菜
Description 题库链接 小 N 是蔬菜仓库的管理员,负责设计蔬菜的销售方案. 在蔬菜仓库中,共存放有 \(n\) 种蔬菜,小 N 需要根据不同蔬菜的特性,综合考虑各方面因素,设计合理的销售方 ...
- SPI Flash(W25Q16DV) 基本操作
读取厂家\设备 ID 发送 90H 指令,再发送 00h 的地址,然后接收即可. 代码如下: void SPIFlashReadID(int *pMID, int *pDID) { SPIFlash_ ...
- .7-浅析webpack源码之WebpackOptionsDefaulter模块
WebpackOptionsDefaulter模块 通过参数检测后,会根据单/多配置进行处理,本文基于单配置,所以会进行到如下代码: if (Array.isArray(options)) { com ...
- 强烈推荐:240多个jQuery插件
概述 jQuery 是继 prototype 之后又一个优秀的 Javascript 框架.其宗旨是—写更少的代码,做更多的事情.它是轻量级的 js 库(压缩后只有21k) ,这是其它的 js 库所不 ...
- 【Java】HashMap源码分析——常用方法详解
上一篇介绍了HashMap的基本概念,这一篇着重介绍HasHMap中的一些常用方法:put()get()**resize()** 首先介绍resize()这个方法,在我看来这是HashMap中一个非常 ...
- Adding a struct into an array(stackoverflow)
Question: So lets say I have a struct like this: struct example_structure { int thing_one; int thing ...
- wangEditor-基于javascript和css开发的 Web富文本编辑器, 轻量、简洁、易用、开源免费(2)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...