zoukankan      html  css  js  c++  java
  • HDU5374 Tetris (2015年多校比赛第7场)大模拟



    思路:

    先写好了几个函数。旋转,四种操作,推断能否够进行合并消除

    题中有好几处要考虑的细节问题,如

    自然下落究竟部时不进行合并的推断,而是当自然下落非法时才推断

    假设消除一行,这一行上面的所以方块仅仅会下落一行,不存在直接下落究竟部的情况

    比赛时题意没有理解好。错了这两个地方。


    另一些写法上的错误。这样的左右移动的题目坐标还是要从1開始,方便很多

    左右移动,假设非法要复原的时候,复原的操作要与移动操作 全然相反。而且这个范围要从0開始,由于移动的时候可能移动到非法的位置。

    赛后看了标程,各种优美简洁的代码。模拟能力还有待加强。


    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<vector>
    #define pb push_back
    #define debug puts("=====================");
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    using namespace std;
    typedef long long ll;
    int t;
    int Map[20][20];     //记录总体
    int updata[20][20];  //记录当前掉落方块
    char ch[1111];
    int a[1111];
    int n;
    int chong()        //推断是否有非法操作
    {
        int sum = 0;
        for(int i=1; i<=12; i++)
            for(int j=1; j<=9; j++)
                if(updata[i][j]) sum++;
        if(sum!=4)
            return 0;
        for(int i=1; i<=12; i++)
            for(int j=1; j<=9; j++)
                if(updata[i][j]+Map[i][j]>1)
                    return 0;
        return 1;
    }
    int zhuan(int type,int x,int y)  //旋转
    {
        if(type==1)
        {
            swap(updata[x-1][y],updata[x][y+1]);
            swap(updata[x-2][y],updata[x][y+2]);
            swap(updata[x-3][y],updata[x][y+3]);
            if(!chong())                          //假设非法,再转回来
            {
                swap(updata[x-1][y],updata[x][y+1]);
                swap(updata[x-2][y],updata[x][y+2]);
                swap(updata[x-3][y],updata[x][y+3]);
            }
        }
        else if(type==2)
        {
            if(updata[x][y]==0)   ///3->4
            {
                swap(updata[x-1][y],updata[x-2][y+1]);
                swap(updata[x-1][y+2],updata[x][y+1]);
                swap(updata[x][y+2],updata[x][y]);
                if(!chong())
                {
                    swap(updata[x-1][y],updata[x-2][y+1]);
                    swap(updata[x-1][y+2],updata[x][y+1]);
                    swap(updata[x][y+2],updata[x][y]);
                }
            }
            else
            {
                if(updata[x-1][y]&&updata[x][y+1]) ///1->2
                {
                    swap(updata[x][y+1],updata[x-2][y]);
                    swap(updata[x][y+2],updata[x-2][y+1]);
                    if(!chong())
                    {
                        swap(updata[x][y+1],updata[x-2][y]);
                        swap(updata[x][y+2],updata[x-2][y+1]);
                    }
                }
                else if(updata[x-1][y]&&!updata[x][y+1]) ///2->3
                {
                    swap(updata[x][y],updata[x-1][y+1]);
                    swap(updata[x-2][y],updata[x-1][y+2]);
                    swap(updata[x-2][y+1],updata[x][y+2]);
                    if(!chong())
                    {
                        swap(updata[x][y],updata[x-1][y+1]);
                        swap(updata[x-2][y],updata[x-1][y+2]);
                        swap(updata[x-2][y+1],updata[x][y+2]);
                    }
                }
                else if(!updata[x-1][y]&&updata[x][y+1]) ///4->1
                {
                    swap(updata[x-1][y+1],updata[x-1][y]);
                    swap(updata[x-2][y+1],updata[x][y+2]);
                    if(!chong())
                    {
                        swap(updata[x-1][y+1],updata[x-1][y]);
                        swap(updata[x-2][y+1],updata[x][y+2]);
                    }
                }
            }
        }
    }
    int  ctrl(char lei,int type)    //控制上下左右
    {
        if(lei=='w')
        {
            if(type==0)
                return 0;
            int xx,yy;
            xx = -9999;
            yy = 9999;
            for(int i=1; i<=12; i++)
                for(int j=1; j<=9; j++)
                    if(updata[i][j])
                        xx = max(xx,i),yy = min(yy,j);   //找到绿色的点,以这个点为基准
            zhuan(type,xx,yy);
        }
        else if(lei=='a')
        {
            for(int i=1; i<=12; i++)
                for(int j=0; j<=10; j++)
                    if(updata[i][j]) swap(updata[i][j],updata[i][j-1]);
            if(!chong())                                //假设非法,再移回来
            {
                for(int i=1; i<=12; i++)
                    for(int j=10; j>=0; j--)
                        if(updata[i][j]) swap(updata[i][j],updata[i][j+1]);
            }
        }
        else if(lei=='d')
        {
            for(int i=1; i<=12; i++)
                for(int j=10; j>=0; j--)
                    if(updata[i][j])  swap(updata[i][j],updata[i][j+1]);
            if(!chong())
            {
                for(int i=1; i<=12; i++)
                    for(int j=0; j<=10; j++)
                        if(updata[i][j])  swap(updata[i][j],updata[i][j-1]);
            }
        }
        else if(lei=='s')
        {
    
            for(int i=13; i>=1; i--)
                for(int j=1; j<=9; j++)
                    if(updata[i][j]) swap(updata[i][j],updata[i+1][j]);
            if(!chong())
            {
                for(int i=1; i<=13; i++)
                    for(int j=1; j<=9; j++)
                        if(updata[i][j]) swap(updata[i][j],updata[i-1][j]);
            }
        }
        return 1;
    }
    int score,tmp,jj,len;
    int di()            //推断能否够合并、消除
    {
        int go = 1;
        for(int i=1; i<=11; i++)
            for(int j=1; j<=9; j++)
            {
                if(updata[i][j]&&updata[i+1][j]==0)
                {
                    if(Map[i+1][j])
                        go = 0;
                }
            }
        for(int j=1; j<=9; j++)
        {
            if(updata[12][j])
                go = 0;
        }
        if(go)
            return 0;
        for(int i=1; i<=12; i++)
            for(int j=1; j<=9; j++)
            {
                if(updata[i][j])
                    Map[i][j]  = updata[i][j];
            }
        while(1)
        {
            int flag = 0;
            int hang = 12;
            for(int i=1; i<=12; i++)
            {
                int sum = 0;
                if(Map[i][1])
                {
                    for(int j=1; j<=9; j++)
                        sum+=Map[i][j];
                }
                if(sum==9)
                {
                  //  cout<<"--------
    ";
                    hang = i;
                    flag = 1;
                    score++;
                    for(int j=1; j<=9; j++)
                        Map[i][j] = 0;
                    break;
                }
            }
            if(flag)
            {
                for(int i=hang-1; i>=1; i--)
                    for(int j=1; j<=9; j++)
                        if(Map[i][j]&&Map[i+1][j]==0)
                            swap(Map[i][j],Map[i+1][j]);
            }
            else
                break;
        }
        return 1;
    }
    
    int main()
    {
        // freopen( "3.out","w",stdout );
        cin>>t;
        int cs =  1;
        while(t--)
        {
            score = 0;
            scanf("%d%s",&n,ch);
            for(int i=0; i<n; i++)
                scanf("%d",&a[i]);
            memset(Map,0,sizeof(Map));
            memset(updata,0,sizeof(updata));
            jj  = 0;
            len=strlen(ch);
            for(int i=0; i<n; i++)    //下落的方块
            {
                tmp = a[i];
                memset(updata,0,sizeof(updata));
                if(a[i]==0)
                {
                    updata[4][4] = 1;
                    updata[3][4] = 1;
                    updata[4][5] = 1;
                    updata[3][5] = 1;
                }
                else if(a[i]==1)
                {
                    updata[4][4] = 1;
                    updata[3][4] = 1;
                    updata[2][4] = 1;
                    updata[1][4] = 1;
                }
                else if(a[i]==2)
                {
                    updata[4][4] = 1;
                    updata[3][4] = 1;
                    updata[4][5] = 1;
                    updata[4][6]  = 1;
                }
                for( ; jj<len; jj++)    //操作编号
                {
                    if(ch[jj]!='p')
                        ctrl(ch[jj],tmp);
                     if(di())        //推断是否进行合并,消除
                    {
                        jj++;
                        break;
                    }
                   ctrl('s',tmp);  //每次自然下落
                }
            }
            printf("Case %d: %d
    ",cs++,score);
        }
        return 0;
    }
    




  • 相关阅读:
    Kubernetes 集成研发笔记
    Rust 1.44.0 发布
    Rust 1.43.0 发布
    PAT 甲级 1108 Finding Average (20分)
    PAT 甲级 1107 Social Clusters (30分)(并查集)
    PAT 甲级 1106 Lowest Price in Supply Chain (25分) (bfs)
    PAT 甲级 1105 Spiral Matrix (25分)(螺旋矩阵,简单模拟)
    PAT 甲级 1104 Sum of Number Segments (20分)(有坑,int *int 可能会溢出)
    java 多线程 26 : 线程池
    OpenCV_Python —— (4)形态学操作
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/6805822.html
Copyright © 2011-2022 走看看