hdu 5374 Tetris 模拟俄罗斯方块

题目链接:

hdu5374

题意:

俄罗斯方块游戏, 给出一个玩家的操作序列(w,a,s,d,p), 和依次出现的n个方块的形状,

问最终玩家消除了几行.

解题思路:

大模拟,想清楚就好写了,

用一个数组保存 所有形状 所有状态下 四个点的相对位置

每进行一次操作时,判断是否合法(越界,重叠)

下落时判断是否重叠 ,如果重叠则不动 将方块加入地图,消行,换下一个方块继续

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int dir[3][4][4][2]={
{ {0,0,0,1,1,0,1,1},{0,0,0,1,1,0,1,1},{0,0,0,1,1,0,1,1},{0,0,0,1,1,0,1,1} }, //方形
{ {0,0,0,1,0,2,0,3},{0,0,1,0,2,0,3,0},{0,0,0,1,0,2,0,3},{0,0,1,0,2,0,3,0} }, //I形
{ {0,0,0,1,1,0,2,0},{0,0,0,1,0,2,1,2},{0,1,1,1,2,1,2,0},{0,0,1,0,1,1,1,2} }  //L形
};
int map[15][15];
char op[1050];
int block[1050];
int ans;

int ok(int x,int y,int b,int state)                //判重叠 越界
{
    int tx,ty;
    for(int i=0;i<4;i++)
    {
        tx=x+dir[b][state][i][0];
        ty=y+dir[b][state][i][1];
        if(tx<1||tx>9||ty<1||ty>12||map[tx][ty]==1)
            return 0;
    }
    return 1;
}

void change_map(int x,int y,int b,int state)      //更新地图
{
    int tx,ty,flag,loc;
    for(int i=0;i<4;i++)
    {
        tx=x+dir[b][state][i][0];
        ty=y+dir[b][state][i][1];
        map[tx][ty]=1;
    }
//    for(int i=8;i>=1;i--){                      //方块下落全过程...
//        for(int j=1;j<=9;j++)
//        printf("%d",map[j][i]);
//        cout<<endl;
//    }
//    printf("-------------\n");
    while(1)
    {
        for(int i=1;i<=8;i++){
            flag=1;
            for(int j=1;j<=9;j++)
                if(map[j][i]==0)
                {
                    flag=0;
                    break;
                }
            if(flag){
                loc=i;
                break;
            }
        }
        if(!flag)
            return;
        ans++;
        for(int i=loc;i<=8;i++)
            for(int j=1;j<=9;j++)
                map[j][i]=map[j][i+1];
    }
}

int main()
{
    int T,n,s_x=4,s_y=9;
    int x,y,state,pos;
    int len;
    int Case=1;
    scanf("%d",&T);
    while(T--)
    {
        memset(map,0,sizeof(map));
        pos=1,x=s_x,y=s_y,state=0;          //每个方块的初始状态
        ans=0;
        scanf("%d",&n);
        scanf("%s",op);
        len=strlen(op);
        for(int i=1;i<=n;i++)
            scanf("%d",&block[i]);

        for(int i=0;i<len;i++)
        {
            if(op[i]=='w'&&ok(x,y,block[pos],(state+1)%4))
                state=(state+1)%4;
            else if(op[i]=='s'&&ok(x,y-1,block[pos],state))
                y--;
            else if(op[i]=='a'&&ok(x-1,y,block[pos],state))
                x--;
            else if(op[i]=='d'&&ok(x+1,y,block[pos],state))
                x++;

            if(ok(x,y-1,block[pos],state))
                y--;
            else {
                change_map(x,y,block[pos],state);
                x=s_x,y=s_y,state=0;
                pos++;
                if(pos>n)
                    break;
            }
        }
        printf("Case %d: %d\n",Case++,ans);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-10 12:21:55

hdu 5374 Tetris 模拟俄罗斯方块的相关文章

hdu 5374 Tetris(模拟)

题目链接:hdu 5374 Tetris 模拟,每次进行操作时判断操作是否合法,合法才执行,否则跳过.每次一个token落地,判断一下是否有消除整行. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; /******* Token **********/ const int C[3] = {1, 2, 4}; const int T[3][4][4][2] = {

HDU 5374 Tetris (2015年多校比赛第7场)

1.题目描写叙述:点击打开链接 2.解题思路:本题要求模拟俄罗斯方块游戏.然而比赛时候写了好久还是没过. 后来补题发现原来是第四步的逻辑实现写错了... 题目中要求假设一整行能够消除,那么仍然运行该步.否则才回到第一步.可是我的代码却是不论能否够消除,都回到第一步.. .补题时候还发现一个地方我的理解出错了.. (可能是我脑洞真的有点大).题目中说假设一整行能够消除,那么它上面的方格要下落.我的理解是下落的方格要一直降落到第一行或者某个支撑物上,最后发现依照这样写,例子都算不正确==.调试了一下

HDU 5374 模拟俄罗斯方块

模拟俄罗斯方块游戏 完全按照俄罗斯方块的规则来做 注意规则即可: 1:每种图形开始出现时绿点均在(4,9)位置 2:先做变换,再下降一格 3:若碰到操作无法被执行的则不执行,依次进行下个操作 #include "stdio.h" #include "string.h" struct Type { int a,b,x,y; }type; char str[1010]; int n,a[1010],ans,flag,mark,now; int mp[20][20]; v

hdu 4964 Emmet(模拟)

题目链接:hdu 4964 Emmet 题目大意: 给定语句,按照语法翻译并输出. 解题思路:用递归模拟文法分析,主要注意几点: 括号并且的情况:(fuck)(you) 括号嵌套的情况:((fuck.you)) 优先输出id,然后是class(题目中有说) 乘法的部分:fuck*2>you*3 (每次执行fuck时,you的地方同样被执行了3次) 其他跑出样例基本没问题,具体看代码. #include <cstdio> #include <cstring> #include

HDU 4891 简单模拟

The Great Pan Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1035    Accepted Submission(s): 355 Problem Description As a programming contest addict, Waybl is always happy to take part in vario

hdu 4194(模拟)

符合三者之一的则不满足规定,求不满足规定的个数.直接模拟. 1.被同一个人审查多次 2.被和自己同一组织的审查 3.被审查次数不等于k 代码如下: 1 /************************************************** 2 * Author : xiaohao Z 3 * Blog : http://www.cnblogs.com/shu-xiaohao/ 4 * Last modified : 2014-06-28 17:36 5 * Filename :

HDU 4903 (模拟+贪心)

Fighting the Landlords Problem Description Fighting the Landlords is a card game which has been a heat for years in China. The game goes with the 54 poker cards for 3 players, where the “Landlord” has 20 cards and the other two (the “Farmers”) have 1

HDU 2100 Lovekey 模拟26进制

Problem Description XYZ-26进制数是一个每位都是大写字母的数字. A.B.C.-.X.Y.Z 分别依次代表一个0 ~ 25 的数字,一个 n 位的26进制数转化成是10进制的规则如下 A0A1A2A3-An-1 的每一位代表的数字为a0a1a2a3-an-1 ,则该XYZ-26进制数的10进制值就为 m = a0 * 26^(n-1) + a1 * 26^(n-2) + - + an-3* 26^2 + an-2*26 + an-1 一天vivi忽然玩起了浪漫,要躲在学校

HDU 4288 Coder(模拟) 附:upper_bound与lower_bound的比较

HDU 4288 题意:太长..点进去自己看吧 思路: 一道模拟题,但直接模拟会卡TLE,所以进行些许优化,将复杂度/5. 简而言之就是用一个有序数组来模拟set. 优化是利用lower_bound函数,这里简介下lower_bound 与 upper_bound 的区别: 摘自:http://blog.csdn.net/weiguang_123/article/details/7987823 lower_bound返回[First,last)中,可以插入value的第一个位置,使得插入后仍旧满