求教CCF俄罗斯方块问题,只得了60分,不知道什么问题

Alredfi 2016-07-24 06:38:19
问题描述

  俄罗斯方块是俄罗斯人阿列克谢·帕基特诺夫发明的一款休闲游戏。
  游戏在一个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

//代码
#include <iostream>

using namespace std;

int main()
{
int a[15][10] = {0};
for(int i = 0;i < 15;i ++)
{
for(int j = 0;j < 10;j ++)
{
cin>>a[i][j];
}
}
int b[4][4] = {0};
for(int i = 0;i < 4;i ++)
{
for(int j = 0;j < 4;j ++)
{
cin>>b[i][j];
}
}
int col = 0,sub = 0;
bool flag_b = false;
cin>>col;
for(int i = 0; i < 4; i ++)
{
for(int j = 0; j < 4; j ++)
{

if(b[j][i] == 1)
{
flag_b = true;
break;
}
}
if(flag_b) break;
sub ++;
}
col = col - sub;
int row_a = 0;
int col_a = col;
bool flag_a = false;
while(true)
{
for(int i = 0; i < 4; i ++)
{
for(int j = 0; j < 4; j ++)
{
if((row_a + i >= 15)&&(b[i][j] == 1))
{
row_a--;
flag_a = true;
break;
}
if((a[row_a + i][col_a + j] == 1)&&(b[i][j] == 1))
{
row_a--;
flag_a = true;
break;
}

}
if(flag_a) break;
}
if(flag_a) break;
row_a ++;

}
for(int i = 0; i < 4; i ++)
{
for(int j = 0; j < 4; j ++)
{
if((a[row_a + i][col_a + j] == 0)&&(b[i][j] == 1))
{
a[row_a + i][col_a + j] = 1;
}
}
}
for(int i = 0; i < 15; i ++)
{
for(int j = 0; j < 10; j ++)
{
if(j != 9)
cout<<a[i][j]<<" ";
else
cout<<a[i][j]<<endl;
}
}
return 0;
}

...全文
1208 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
懒虫Walker 2019-10-09
  • 打赏
  • 举报
回复
//我用的是Java,这个是100分的,在下面代码中有几行注释,在我用注释里面的代码顺序的时候得的就是60分
//原因是我没有考虑到板块图案4x4里面有某一列是没有方格的时候应该设定不更改板块图案与下方板块的最小距离,这导致如果把第5
//行第3列的输入从0变为1的时候,我的板块就卡在上面掉不下去了
import java.util.Scanner;

//俄罗斯方块
class Test2 {
int arr[][] = new int[15][10];

public Test2(int a[][]) {
arr = a;
}

void addTetris(int tetris[][], int lc) {
int d[] = { 15, 15, 15, 15 }, minD = 15, top = 0, bottom = 15, k = 0;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
arr[i][j + lc] = tetris[i][j];
}
}
for (int j = lc; j < lc + 4; j++) {
for (int i = 0; i < 4; i++) {
if (arr[i][j] == 1)
top = i;
}
for (int i = 14; i > 3; i--) {
if (arr[i][j] == 1)
bottom = i;
}
d[k] = bottom - top;

if (minD > d[k]&&top!=0) //bottom = 15;
minD = d[k]; //top = 0;
bottom = 15; //if (minD > d[k])
top = 0; // minD = d[k];
k++;
}
minD--;
drop(tetris, lc, minD);

}

void drop(int t[][], int lc, int d) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
arr[i][j + lc] = 0;
}
}
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++) {
if (t[i][j] == 1)
arr[i + d][j + lc] = 1;
}
}

void print() {
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 10; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
}
}

public class Main {
public static void main(String[] args) {
int arr[][] = new int[15][10];
int leftColumn;
int tetris[][] = new int[4][4];
Scanner in = new Scanner(System.in);
for (int i = 0; i < 15; i++) {
for (int j = 0; j < 10; j++) {
arr[i][j] = in.nextInt();
}
}
Test2 test = new Test2(arr);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
tetris[i][j] = in.nextInt();
}
}
leftColumn = in.nextInt() - 1;
test.addTetris(tetris, leftColumn);
test.print();
in.close();
}
}
Alredfi 2016-09-28
  • 打赏
  • 举报
回复
谢谢大家,找到bug了,是因为有一种下落停止的状态没考虑
kang92 2016-08-03
  • 打赏
  • 举报
回复
你去下载我的资源,里面有两个俄罗斯方块的例子。或者你把邮箱给我,我发给你。
赵4老师 2016-07-28
  • 打赏
  • 举报
回复
代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒:再牛×的老师也无法代替学生自己领悟和上厕所! 单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。
真·skysys 2016-07-28
  • 打赏
  • 举报
回复
(算法问题最好去网上搜题解翻博客,在论坛里面没人有功夫去帮你看orz虽然我也是研究算法的)

64,651

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧