HDU 5374 Tetris 俄罗斯方块 模拟

来源:互联网 发布:苹果平板电脑淘宝下载 编辑:程序博客网 时间:2024/04/28 16:19

这道题是喜闻乐见的大模拟题。

题目大意:在一个9X12的格子中玩俄罗斯方块,给定所有可能的方块形态,给定方块的掉落顺序,给定操作,w表示旋转,a表示左移,b表示右移,d表示下落一格(实际下落两格),p表示pass(即下落一格),输入数据保证不会GameOver,求最后的分数。

题意虽然简单,但是由于编程复杂度等众多原因,考场上写的人不多。这里有几个可以简化代码的trick,由于旋转最大循环节为4,方块最大长宽也为4,那么我们可以把每一种方块的形态用4*4*4的数组存下来,这样判断以及旋转操作都很容易实现;还有就是方块在移动过程中,只需把基点即左下角的点的坐标记下来,不需要每操作都把当前状态表示出来。

虽然我考场上用了这俩技巧,然而还是没有调出来哪里写错了,考完以后发现判断消除行的时候要从上往下枚举...非常可惜。

144737672015-08-12 11:19:26Accepted53740MS1412K2027 BG++Kurama

#include <cstdio>#include <cstdlib>#include <cstring>#define MAXN 1001using namespace std;int order[MAXN],n,no,st,X,Y,score;//order为方块下落顺序,no表示该方块处于第几种旋转状态//X,Y为现在的位置,score统计分数 bool Brick[3][4][4][4]={{    {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}},    {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}},    {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}},    {{1,1,0,0},{1,1,0,0},{0,0,0,0},{0,0,0,0}}},{    {{1,0,0,0},{1,0,0,0},{1,0,0,0},{1,0,0,0}},    {{1,1,1,1},{0,0,0,0},{0,0,0,0},{0,0,0,0}},    {{1,0,0,0},{1,0,0,0},{1,0,0,0},{1,0,0,0}},    {{1,1,1,1},{0,0,0,0},{0,0,0,0},{0,0,0,0}},},{    {{1,1,1,0},{1,0,0,0},{0,0,0,0},{0,0,0,0}},    {{1,0,0,0},{1,0,0,0},{1,1,0,0},{0,0,0,0}},    {{0,0,1,0},{1,1,1,0},{0,0,0,0},{0,0,0,0}},    {{1,1,0,0},{0,1,0,0},{0,1,0,0},{0,0,0,0}}}};//为了方便我们将所有类型的方块存成4*4 char oper[MAXN];//操作字符串 bool dB,tetris[20][20];//dB表示是否有下落完全的方块,tetris保存每个方块的最后状态 void Fresh(){    for(int i=0;i<4;i++)        for(int j=0;j<4;j++)            if(Brick[order[no]][st][i][j])                tetris[Y+i][X+j]=true;}//更新状态 bool Attempt(char op){    int x=X,y=Y,s=st,ty=order[no];    if(op=='w')s=(st+1)%4;else    if(op=='s')y--;else    if(op=='d')x++;else    if(op=='a')x--;    if(y==0 || x==0)return false;    for(int i=0;i<4;i++)        for(int j=0;j<4;j++)            if(Brick[ty][s][i][j])                if(x+j>9 || tetris[y+i][x+j])return false;    X=x;Y=y;st=s;    return true;}//尝试操作,若操作不合法则忽略 bool check(int r){    for(int i=1;i<=9;i++)if(!tetris[r][i])return false;    return true;}//检查是否可以消除 void delet(int r){    for(int i=r;i<=12;i++)        for(int j=1;j<=9;j++)tetris[i][j]=tetris[i+1][j];}//消除满行 void simulate(char op){    if(!dB){X=4,Y=9,st=0;dB=true;}    if(op!='p')Attempt(op);    if(Attempt('s'))return; //     else{        Fresh();        dB=false;        no++;        for(int i=12;i>=1;i--)            if(check(i)){                delet(i);                score++;            }    }}//模拟操作 int main(){    int t;    scanf("%d",&t);    for(int casen=1;casen<=t;casen++){        memset(tetris,0,sizeof tetris);        no=score=0;dB=false;        scanf("%d%s",&n,oper);        for(int i=0;i<n;i++)scanf("%d",&order[i]);        int len=strlen(oper);        for(int i=0;i<len;i++)simulate(oper[i]);        printf("Case %d: %d\n",casen,score);    }    return 0;}


0 0