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;
    }
    




  • 相关阅读:
    Javascript之让图片固定在一个位置
    Android之AIDL实现Demo
    android listview 上下边缘的模糊去掉
    Android中Application设置全局变量以及传值
    Android之在Bitmap上涂鸦效果
    Android之TabHost重定义
    Android数据库升级实例,已更新
    Android之更新ListView,位置置顶的问题
    Android之Parcelable使用
    Asp.Net 2.0 防盗下载文件·············
  • 原文地址:https://www.cnblogs.com/slgkaifa/p/6805822.html
Copyright © 2011-2022 走看看