zoukankan      html  css  js  c++  java
  • HDU 3013 Tetris 【恶心的模拟题俄罗斯方块】

    http://acm.hdu.edu.cn/showproblem.php?pid=3013

    先发泄一下,这道题写了24+小时,太恶心了..感谢黑大的一个童鞋挑出了我思路的bugO(∩_∩)O~~看着他9000B+的代码开始羡慕后来..hiahia~~3000B+搞定~~

    8229075 2013-05-04 00:12:03 Accepted 3013 0MS 332K 3788 B G++ Dream
    8229071 2013-05-04 00:10:42 Presentation Error 3013 0MS 328K 3790 B G++ Dream
    8229069 2013-05-04 00:10:39 Compilation Error 3013 0MS 0K 931 B G++ Dream
    8229065 2013-05-04 00:10:02 Presentation Error 3013 0MS 328K 3790 B G++ Dream
    8228963 2013-05-03 23:45:21 Wrong Answer 3013 0MS 328K 3791 B G++ Dream
    8228891 2013-05-03 23:35:36 Wrong Answer 3013 0MS 328K 3881 B G++ Dream
    8221926 2013-05-03 07:52:24 Wrong Answer 3013 0MS 328K 3258 B G++ Dream
    8221231 2013-05-02 22:43:47 Wrong Answer 3013 0MS 328K 3243 B G++ Dream

    好吧~~先兴奋一下

    解题思路:

    一共有7种形状的方块,每种4个角度,4个单位,每个单位用二维相对坐标表示出来,dir[][][][]数组

    对于每一块下落后从下到上找到安全点,试着下落状态map[][]然后进行消除。如果没有越界的state[][]更新;

    注意:**假设块7下落发生越界,但是可以将某一行消除掉,更新后的状态没有越界的,那么继续下落方块

    代码如下:

    View Code
    #include <stdio.h>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    int dir[7][4][4][2]={
    {{{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}}},
    {{{0, 0}, {0, 1}, {0, 2}, {1, 0}}, {{0, 0}, {1, 0}, {2, 0}, {2, 1}}, {{0, 0}, {0, 1}, {0, 2}, {-1, 2}}, {{0, 0}, {0, 1}, {1, 1}, {2, 1}}},
    {{{0, 0}, {0, 1}, {0, 2}, {1, 2}}, {{0, 0}, {0, 1}, {1, 0}, {2, 0}}, {{0, 0}, {1, 0}, {1, 1}, {1, 2}}, {{0, 0}, {0, 1}, {-1, 1}, {-2, 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}, {1, 0}, {1, 1}}},
    {{{0, 0}, {0, 1}, {1, 1}, {1, 2}}, {{0, 0}, {1, 0}, {0, 1}, {-1, 1}}, {{0, 0}, {0, 1}, {1, 1}, {1, 2}}, {{0, 0}, {1, 0}, {0, 1}, {-1, 1}}}, 
    {{{0, 0}, {0, 1}, {0, 2}, {1, 1}}, {{0, 0}, {1, 0}, {2, 0}, {1, 1}}, {{0, 0}, {0, 1}, {0, 2}, {-1, 1}}, {{0, 0}, {0, 1}, {-1, 1}, {1, 1}}},
    {{{0, 0}, {0, 1}, {-1, 1}, {-1, 2}}, {{0, 0}, {1, 0}, {1, 1}, {2, 1}}, {{0, 0}, {0, 1}, {-1, 1}, {-1, 2}}, {{0, 0}, {1, 0}, {1, 1}, {2, 1}}}
    };  //7种形状4种度数4个点的相对x,y坐标 
                            
    int map[30][15]; //记录下落后的状态 
    int state[30][15];  //记录前状态 
    int sum[30];  //标记改行有多少个空格被占据 
    int safe(int x, int y)
    {
        if(x>0&&y>0&&y<=10&&map[x][y]==0)  return 1;
        return 0;
    }
    int main()
    {
        int m, id, de, pos, i, j, k, x1, y1, x2, y2, x3, y3, x4, y4, jj;
        int frx1, frx2, frx3, frx4, fry1, fry2, fry3, fry4;
        while(scanf("%d", &m)!=EOF)
        {
            memset(map, 0, sizeof(map));
            memset(sum, 0, sizeof(sum));
            memset(state, 0, sizeof(state)); 
            int flag=0; //标记最终是否能赢 
            for(i=0; i<m; i++)
            {
                scanf("%d%d%d", &id, &de, &pos);
                if(flag==1) continue; 
                id--; de/=90;
                for(j=23; j>0; j--)  //从上往下找 
                {
                    x1=j+dir[id][de][0][0], y1=pos+dir[id][de][0][1];
                    x2=j+dir[id][de][1][0], y2=pos+dir[id][de][1][1];
                    x3=j+dir[id][de][2][0], y3=pos+dir[id][de][2][1];
                    x4=j+dir[id][de][3][0], y4=pos+dir[id][de][3][1];
                    if(safe(x1, y1)&&safe(x2, y2)&&safe(x3, y3)&&safe(x4, y4))
                    {
                        frx1=x1, frx2=x2, frx3=x3, frx4=x4;
                        fry1=y1, fry2=y2, fry3=y3, fry4=y4;
                    }  
                    else break;
                }
                if(j==23) flag=1;
                if(flag) continue;
                map[frx1][fry1]=1, map[frx2][fry2]=1, map[frx3][fry3]=1, map[frx4][fry4]=1;
                sum[frx1]++, sum[frx2]++, sum[frx3]++, sum[frx4]++; 
                
                for(j=1; j<=20; j++)
                {
                    while(sum[j]==10) //改行被占据,消除改行 以上的行平移下来 
                    {
                        for(jj=j+1; jj<25; jj++)
                        {
                            for(k=1; k<=10; k++)
                                map[jj-1][k]=map[jj][k];
                            sum[jj-1]=sum[jj];
                        }
                    }
                }
                for(j=21; j<25; j++)
                    if(sum[j]) flag=1;//消除后存在越界情况,游戏结束 
                if(flag!=1) 
                {
                    for(j=0; j<=20; j++)
                        for(jj=0; jj<=10; jj++)
                            state[j][jj]=map[j][jj];
                }
            }
            printf("+--------------------+\n");
            for(i=20; i>=1; i--)
            {
                printf("|");
                for(j=1; j<=10; j++)
                {
                    if(state[i][j]==1) printf("[]");
                    else printf("..");
                }
                printf("|\n");
            }
            printf("+--------------------+\n\n");
        }
        return 0;   
    }
  • 相关阅读:
    go语言编程之旅笔记5
    go语言编程之旅笔记4
    go语言编程之旅笔记3
    go语言编程之旅笔记1~2
    minikube使用记录
    Azure Sql : Could not find stored procedure 'sp_addlinkedserver'.
    Jenkins SVN WebDeploy远程服务器
    sqlserver使用cte实现某列按字符分隔成多行
    openstack安装记录
    C语言中的bzero函数
  • 原文地址:https://www.cnblogs.com/Hilda/p/3058606.html
Copyright © 2011-2022 走看看