ccf刷题 俄罗斯方块c++ 50分

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

写俄罗斯方块的程序只有50分
逻辑也是比较坑坑巴巴
干干巴巴麻麻赖赖的一点都不圆润
有没有大神看到的可以指导一下的哦 嘤嘤嘤

#include <iostream>

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
int main(int argc, char** argv) {
	int a[18][10],b[4][4];
	for(int i=0;i<3;i++){
		for(int j=0;j<10;j++){
			a[i][j]=0;
		}
	}
	for(int i=3;i<18;i++){
		for(int j=0;j<10;j++){
			cin>>a[i][j];
		}
	}
//	int a[18][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,1,1,1,0,0,0,0,0,0},
//				   {0,1,1,1,0,0,0,0,0,0},
//				   {0,0,0,0,0,0,0,0,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,1,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,1,1,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,1,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}};

	for(int i=0;i<4;i++){
		for(int j=0;j<4;j++){
			cin>>b[i][j];
		}
	}
//	int b[4][4]={{0,0,1,0},
//				 {0,0,1,0},
//				 {0,0,1,0},
//				 {0,0,1,0}};
//	int c=5;
	int c;
	cin>>c;
	bool left;
	for(int j=0;j<4;j++){
		left=true;
		for(int i=0;i<4;i++){
			if(b[i][j]!=0){
				left=false;
				break;
			}
		}
		if(left){
			c=c-1;	
		}
		if(!left){
			break;
		}
	}		
	bool stop;
	stop=false;
	int stoph;
	for(int i=0;i<18;i++){
		for(int j=3;j>=0;j--){
			for(int k=0;k<4;k++){
				int s=a[i+j][c+k]+b[j][k];
				if(s>=2){
					stoph=i-1;
					stop=true;
					break;
				}
			}
		}
		if(stop) break;	
	}
	if(stop&&stoph>0){
 		for(int i=0;i<4;i++){
			int newh=stoph+i;
			for(int j=0;j<4;j++){
				int newl=c+j;
				if(a[newh][newl]==0){
					a[newh][newl]=b[i][j];
				}
			}	
 		}			
	}else if(!stop&&stoph>0){
		int newh = 11;
		for(int i=0;i<4;i++){
			for(int j=0;j<4;j++){
				if(a[newh+i][c+j]==0){
					a[newh+i][c+j]=b[i][j];
				} 
			}
		}
	}
	for(int i=3;i<18;i++){
		for(int j=0;j<10;j++){
			cout<<a[i][j]<<" ";
		}
		cout<<endl;
	}
	return 0;
}

大致思路如下:
首先给大矩阵加前三行,方便在二重遍历时小块可以从第一行开始计算是否被重叠
每个小块都从最底一行开始遍历,若与大棋盘有重叠则两点之和大于1,停止下落
停止下落后将小块的值赋值给大棋盘
难道是左右边界也有问题
啊啊啊 好烦呀不想思考了
去看大神代码了 嘤嘤嘤

猜你喜欢

转载自blog.csdn.net/qq_42910523/article/details/83684489
今日推荐