俄罗斯方块问题

问题:Tetris (Russian: Тeтрис) is a puzzle video game originally designed and programmed by Alexey Pajitnov in the Soviet Union. The Tetris game is a popular use of tetrominoes, the four element special case of polyominoes.The seven kinds of tetrominoes are listed below.

We use ‘I’, ‘J’, ‘L’, ‘O’ to stand for the tetrominoes in the top row, and ‘S’, ‘T’, ‘Z’ for the ones in the bottom row.
I enjoy it a lot. But unfortunately, I am not so good at it. So I want a computer program to help me in this game. Given the shapes and falling order of some tetrominoes, and the width and height of a rectangle, the program should check out whether those tetrominoes can fully fill in that rectangle.
There are rules. First of all, you can rotate or move a tetromino, but you can’t flip it. Secondly, let’s assume the height of the screen is unlimited, so there is always enough space to rotate or move a tetromino. Thirdly, to simplify the problem, any tetromino should not be placed under other tetrominos which fell earlier than it. For example:

In the graph above, T is placed under S. If T fell earlier than S, that’s OK. But if T came latter than S, that’s not allowed.
To make it easy, you get only ten tetrominoes in the game. So the area of the rectangle to be filled in is always 40.

Input
The input contains no more than 1000 test cases.Each test case contains two lines which are formatted as follows.
n m
t1 t2 ...... t10
n, m are integers indicating the width and height of the rectangle. It is promised that n*m=40. The next line contains 10 characters, each indicating a tetromino. t1 is the first falling tetromino and t10 is the last.
The input is ended by n=0 and m=0

Output
For each test case, if those tetrominoes can fill the rectangle, print Yes in a single line, else print No.

Sample Input
10 4
I I L Z O J O T T J
4 10
O Z J S T O I J I S
0 0

Sample Output
Yes
No

Hint
Here is a picture illustrated the first case. It may be helpful for you to understand the problem.

回答:题意大概是给你十个俄罗斯方块,问你能否拼成指定长宽的矩形,方块下落的顺序是严格确定的,后下落的方块不能落在先下落的方块之下写出算法。

#include <cstdio>
#include <cstring>
#include <cstdlib>

char tet[20];   //记录方块的下降次序
int box[45];    //把方块分成小格子,记录每列有多个小格子
int m, n;

bool DFS( int cur )
{
    if ( cur == 10 ) return true;

switch( tet[cur] )
    {
        case ‘I‘ :
        for ( int i = 0; i < n; i++ )
        {
            if ( box[i] + 4 <= m )   //判断能不能竖着放
            {
                box[i] += 4;
                if ( DFS( cur + 1 ) ) return true;
                box[i] -= 4;
            }
            if ( i + 3 < n && box[i] == box[i + 1] && box[i + 1] == box[i + 2] && box[i + 2] == box[i + 3] && box[i] + 1 <= m )    //能不能横着放
            {
                for ( int j = i; j < i + 4; j++ ) ++box[j];
                if ( DFS( cur + 1 ) ) return true;
                for ( int j = i; j < i + 4; j++ ) --box[j];
            }
        }
        break;

case ‘O‘:
        for ( int i = 0; i < n; i++ )
        {
            if ( i + 1 < n && box[i] == box[i + 1] && box[i] + 2 <= m )
            {
                box[i] += 2;
                box[i + 1] += 2;
                if ( DFS( cur + 1 ) ) return true;
                box[i] -= 2;
                box[i + 1] -= 2;
            }
        }
        break;

case ‘L‘ :
        for ( int i = 0; i < n; i++ )
        {
            if ( i + 1 < n && box[i] + 3 <= m && box[i] == box[i + 1] )    //正着放L
            {
                box[i] += 3;
                box[i + 1] += 1;
                if ( DFS( cur + 1 ) ) return true;
                box[i] -= 3;
                box[i + 1] -= 1;
            }

if (i + 2 < n && box[i] + 1 == box[i + 1] && box[i + 1] == box[i + 2] && box[i] + 2 <= m && box[i + 1] + 1 <= m )    //顺时针旋转90°
            {
                box[i] += 2;
                box[i + 1] += 1;
                box[i + 2] += 1;
                if ( DFS( cur + 1 ) ) return true;
                box[i] -= 2;
                box[i + 1] -= 1;
                box[i + 2] -= 1;
            }

if (i + 1 < n && box[i] + 1 <= m && box[i + 1] + 3 <= m && box[i + 1] + 2 == box[i] )    //顺时针旋转180°
            {
                box[i] += 1;
                box[i + 1] += 3;
                if ( DFS( cur + 1 ) ) return true;
                box[i] -= 1;
                box[i + 1] -= 3;
            }

if (i + 2 < n && box[i] == box[i + 1] && box[i + 1] == box[i + 2] && box[i + 2] + 2 <= m )    //顺时针旋转270°
            {
                box[i] += 1;
                box[i + 1] += 1;
                box[i + 2] += 2;
                if ( DFS(cur + 1) ) return true;
                box[i] -= 1;
                box[i + 1] -= 1;
                box[i + 2] -= 2;
            }

}
        break;

case ‘J‘ :
        for ( int i = 0; i < n; i++ )
        {
            if (i + 1 < n && box[i] == box[i + 1] && box[i + 1] + 3 <= m )         //0
            {
                box[i] += 1;
                box[i + 1] += 3;
                if ( DFS(cur + 1) ) return true;
                box[i] -= 1;
                box[i + 1] -= 3;
            }
            if (i + 2 < n && box[i] == box[i + 1] && box[i + 1] == box[i + 2] && box[i] + 2 <= m)         //90
            {
                box[i] += 2;
                box[i + 1] += 1;
                box[i + 2] += 1;
                if ( DFS( cur + 1 ) ) return true;
                box[i] -= 2;
                box[i + 1] -= 1;
                box[i + 2] -= 1;
            }
            if (i + 1 < n && box[i] + 2 == box[i + 1] && box[i] + 3 <= m && box[i + 1] + 1 <= m )         //180
            {
                box[i] += 3;
                box[i + 1] += 1;
                if ( DFS( cur + 1 ) ) return true;
                box[i] -= 3;
                box[i + 1] -= 1;
            }
            if (i + 2 < n && box[i] == box[i + 1] && box[i + 2] + 1 == box[i + 1] && box[i] + 1 <= m && box[i + 2] + 2 <= m)         //270
            {
                box[i] += 1;
                box[i + 1] += 1;
                box[i + 2] += 2;
                if ( DFS(cur + 1) ) return true;
                box[i] -= 1;
                box[i + 1] -= 1;
                box[i + 2] -= 2;
            }
        }
        break;

case ‘Z‘ :
        for ( int i = 0; i < n; i++ )
        {
            if (i + 2 < n && box[i + 2] == box[i + 1] && box[i + 1] + 1 == box[i] && box[i] + 1 <= m && box[i + 1] + 2 <= m )  //0
            {
                box[i] += 1;
                box[i + 1] += 2;
                box[i + 2] += 1;
                if ( DFS( cur + 1 ) ) return true;
                box[i] -= 1;
                box[i + 1] -= 2;
                box[i + 2] -= 1;
            }
            if (i + 1 < n && box[i] + 1 == box[i + 1] && box[i] + 2 <= m && box[i + 1] + 2 <= m)   //90
            {
                box[i] += 2;
                box[i + 1] += 2;
                if ( DFS( cur + 1 ) ) return true;
                box[i] -= 2;
                box[i + 1] -= 2;
            }
        }
        break;

case ‘S‘ :
        for ( int i = 0; i < n; i++ )
        {
            if (i + 2 < n && box[i] == box[i + 1] && box[i + 1] + 1 == box[i + 2] && box[i + 1] + 2 <= m && box[i + 2] + 1 <= m )    //0
            {
                box[i] += 1;
                box[i + 1] += 2;
                box[i + 2] += 1;
                if ( DFS(cur + 1) ) return true;
                box[i] -= 1;
                box[i + 1] -= 2;
                box[i + 2] -= 1;
            }
            if (i + 1 < n && box[i + 1] + 1 == box[i] && box[i] + 2 <= m && box[i + 1] + 2 <= m )    //90
            {
                box[i] += 2;
                box[i + 1] += 2;
                if ( DFS(cur + 1) ) return true;
                box[i] -= 2;
                box[i + 1] -= 2;
            }
        }
        break;

case ‘T‘ :
        for ( int i = 0; i < n; i++ )
        {
            if ( i + 2 < n && box[i] == box[i + 1] && box[i + 1] == box[i + 2] && box[i + 1] + 2 <= m ) //0
            {
                box[i] += 1;
                box[i + 1] += 2;
                box[i + 2] += 1;
                if ( DFS( cur + 1 ) ) return true;
                box[i] -= 1;
                box[i + 1] -= 2;
                box[i + 2] -= 1;
            }

if ( i + 1 < n && box[i] + 1 == box[i + 1] && box[i] + 3 <= m ) //90
            {
                box[i] += 3;
                box[i + 1] += 1;
                if ( DFS( cur + 1 ) ) return true;
                box[i] -= 3;
                box[i + 1] -= 1;
            }
            if ( i + 2 < n && box[i] == box[i + 2] && box[i + 1] + 1 == box[i] && box[i + 1] + 2 <= m ) //180
            {
                box[i] += 1;
                box[i + 1] += 2;
                box[i + 2] += 1;
                if ( DFS( cur + 1 ) ) return true;
                box[i] -= 1;
                box[i + 1] -= 2;
                box[i + 2] -= 1;
            }

if ( i + 1 < n && box[i + 1] + 1 == box[i] && box[i + 1] + 3 <= m ) //270
            {
                box[i] += 1;
                box[i + 1] += 3;
                if ( DFS( cur + 1 ) ) return true;
                box[i] -= 1;
                box[i + 1] -= 3;
            }
        }
        break;
    }
    return false;
}

int main()
{
    while ( scanf( "%d%d", &n, &m ), n || m )
    {
        for ( int i = 0; i < 10; i++ )
        {
            getchar();
            tet[i] = getchar();
        }

memset( box, 0, sizeof(box) );

if ( DFS(0) ) puts("Yes");
        else puts("No");
    }
    return 0;
}

时间: 2024-11-12 02:36:13

俄罗斯方块问题的相关文章

很棒的计算机入门课程:公开课从与非门到俄罗斯方块(第二部分)

博客中的文章均为meelo原创,请务必以链接形式注明本文地址 Build a Modern Computer from First Principles: Nand to Tetris Part II (project-centered course) by: Noam Nisan & Shimon Schocken from: Hebrew University of Jerusalem 课程链接:https://www.coursera.org/learn/nand2tetris2/home

俄罗斯方块

俄罗斯方块游戏自动机 <用electron制作俄罗斯方块游戏> 后续文章,智能程序玩俄罗斯方块游戏. 背景 前不久用ES6完成了基本的俄罗斯方块游戏,今天已经完成了一个初步的智能算法,可以自动玩俄罗斯方块了,让自己的想法朝实现更近了一步. 效果图 第一次运行,消除了1398行,窃喜! 程序结构 主要关注智能算法,结构简单化,全部放在了index.js中. 用定时器驱动游戏 function autoPlayClick(){ isAutoPlay = document.getElementByI

C语言:俄罗斯方块

大一下学期,第一节c语言课程设计,老师分享了一个基于C语言的俄罗斯方块的游戏,让我们感受. 如果你想用Mac系统跑的话,也不是不行,但是得解决一些问题.在语言程序中#include<windows.h>这个是基于windows下的头文件,用在Mac的Xcode软件会出现Symbol not found的问题.自己百度了一下,一个是装虚拟机,另一个是把报错的地方修改成Xcode的代码,不用windows特有代码.还有一个就是定义了一个全局的变量,让工程不走windows.h.用Mac的同学们可以

关于俄罗斯方块游戏软件C语言初步感受

C语言课程设,老师先给我们发了一个使用C语言做的飞机游戏,第一次看到用C语言做的游戏,虽然画面简陋,但却是真正的游戏.后老师又给我们发了用C语言做的俄罗斯方块的游戏 int x;     //中心方块的x轴坐标 int y;     //中心方块的y轴坐标 int flag;    //标记方块类型的序号 int next;    //下一个俄罗斯方块类型的序号 int speed;    //俄罗斯方块移动的速度 int count;    //产生俄罗斯方块的个数 int score;  

俄罗斯方块软件:C语言应用初步感受

C语言课程设以一节课,老师提供了一个C语言的飞机游戏让我们感受,上学期C语言课程,主要是各种语句的练习,这次是用以前的知识来感受一个实际的系统. 首先安装c-free,然后运行程序. 游戏程序看似简单,但是用C语言来实现还是第一次见,感到很惊奇. 分析一下程序,感觉没有太复杂的,就是上学期学习的简单语句的组合,但是运用的非常好.首先看看用到了几种语句: 1.首先是在屏幕上显示的语句printf printf("俄罗斯方块"); gotoxy(hOut,FrameX+2*Frame_wi

俄罗斯方块和贪吃蛇游戏软件:C语言应用初始感受

C语言课程设以一节课,老师提供了一个C语言的飞俄罗斯方块让我们感受,我们所学的C语言课程,主要是各种语句的练习,这次是用我们所学过的知识来感受一个实际的系统. 首先安装c-free,然后是将代码贴进去运行 界面虽然有点简单,但这确实使用C语言做出来的游戏. 分析一下程序,感觉没有太复杂的,就是上学期学习的简单语句的组合,但是用的非常好.首先看看用到了几种语句: 1.首先是在屏幕上显示的语句printf, 2.另外一个就是多条件判断switch--case 应用方法 switch(tetris->

俄罗斯方块游戏:C语言程序设计初步感受

C语言课程设以一节课,老师提供了一个C语言的俄罗斯方块游戏让我们感受,本学期C语言课程,主要是各种语句的练习,这次是用以前的知识来感受一个实际的系统. 首先安装c-free,然后打开老师所发给我们的小程序. 界面很简单,没想到C语言还能做这么有意思的东西,真是没有想到. 分析一下程序,感觉比较太复杂的,但就是本学期学习的简单语句的组合,运用起来如此神奇. 1.首先是在屏幕上显示的语句printf 2.运用for语句建立窗口 for(i=2;i<2*Frame_width-2;i+=2) { go

前端作品五之——完美俄罗斯方块

---恢复内容开始--- 1.功能概述 实现传统的俄罗斯方块的功能.有几种固定形状和颜色的方块随机下落,满一行则此行消除.并让积分增加100,使用本地存储功能将方块的状态和得分存起来.在下次进行游戏的时候载入数据,并在游戏中进行存储操作. 2.选材布局 用canvas组件画方格图.用JavaScript语言实现逻辑功能. 3.功能实现与体会 源码中本人发现了几处bug, 1.测试发现在旋转操作频繁的时候,会出现方块严重错位,或丢失,出现一些匪夷所思的现象. 经分析,是旋转操作的处理出现的问题.

用JAVA写的俄罗斯方块

业务需求->业务对象模型(对象关系)->数据建模->类的设计->概要编码->详细功能设计 基本规则: 1)首先呢,俄罗斯方块都是由一个个小格子构成的,我们叫它Cell: 行宽:10,列高:20,以每个小正方形为单位 2)其次,所有的俄罗斯方块都是一组由4个小型正方形组成的规则图形,我们叫它Tetromino    分别为:S.Z.L.J.I.O.T这几种 哈哈,有了这样的分析,就可以构建数据结构设计了 数据结构设计: Cell     格子|--     int row 行|

H5版俄罗斯方块(3)---游戏的AI算法

前言: 算是"long long ago"的事了, 某著名互联网公司在我校举行了一次"lengend code"的比赛, 其中有一题就是"智能俄罗斯方块". 本着一向甘做分母, 闪耀分子的绿叶精神, 着着实实地打了一份酱油. 这次借学习H5的机会, 再来重温下俄罗斯方块的AI编写. 本系列的文章链接如下: 1). 需求分析和目标创新 2). 游戏的基本框架和实现 这些博文和代码基本是同步的, 并不确定需求是否会改变, 进度是否搁置, 但期翼自己能