POJ 3106Flip and Turn(模拟)

Flip and Turn
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 957 Accepted: 330

Description

Let us define a set of operations on a rectangular matrix of printable characters.

A matrix A with m rows (1-st index) and n columns (2-nd index) is given. The resulting matrix B is defined as follows.

  • Transposition by the main diagonal (operation identifier is ‘1’): Bj,i = Ai,j
  • Transposition by the second diagonal (‘2’): Bnj+1,mi+1 = Ai,j
  • Horizontal flip (‘H’): Bmi+1,j = Ai,j
  • Vertical flip (‘V’): Bi,nj+1 = Ai,j
  • Rotation by 90 (‘A’), 180 (‘B’), or 270 (‘C’) degrees clockwise; 90 degrees case: Bj,mi+1 = Ai,j
  • Rotation by 90 (‘X’), 180 (‘Y’), or 270 (‘Z’) degrees counterclockwise; 90 degrees case: Bnj+1,i = Ai,j

You are given a sequence of no more than 100 000 operations from the set. Apply the operations to the given matrix and output the resulting matrix.

Input

At the first line of the input file there are two integer numbers — m and n (0 < mn ≤ 300). Then there are m lines with n printable characters per line (we define a printable character as a symbol with ASCII code from 33 to 126 inclusive). There will be no additional symbols at these lines.

The next line contains the sequence operations to be performed, specified by their one-character identifiers. The operations should be performed from left to right.

Output

Two integer numbers, the number of rows and columns in the output matrix. Then the output matrix must follow, in the same format as the input one.

Sample Input

3 4
0000
a0b0
cdef
A1

Sample Output

3 4
cdef
a0b0
0000


题目大意:给你一个m*n的矩阵,通过顺时针旋转,逆时针旋转,水平翻转,垂直翻转,对角线旋转,反对角线旋转变换得到新矩阵。但是不能直接对原矩阵操作,时间复杂度为O(10^5*10^5),会超时,但是如何保存变化的过程呢,我们不需要知道变化过程,只需要知道结果即可。由于旋转翻转都是中心对称的,可以采用一个2*2的小正方形记录变化情况,然后小矩阵变化得出最终结果之后再相应变化大矩阵。时间复杂度为O(10^5*5)

      题目地址:Flip and Turn

AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
using namespace std;
char a[305][305];
char b[305][305];
char str[100005];
int m,n;
int tb[3][3];

void con1()
{
    int i,j;
    for(i=1; i<=n; i++)
    {
        for(j=1; j<=m; j++)
        {
            b[i][j]=a[j][i];
        }
    }

    for(i=1; i<=n; i++)
    {
        for(j=1; j<=m; j++)
            a[i][j]=b[i][j];
        a[i][j]='\0';
    }
    swap(n,m);
}

void con2()
{
    int i,j;
    for(i=1; i<=m; i++)
    {
        for(j=1; j<=n; j++)
        {
            b[n-j+1][m-i+1]=a[i][j];
        }
    }

    for(i=1; i<=n; i++)
    {
        for(j=1; j<=m; j++)
            a[i][j]=b[i][j];
        a[i][j]='\0';
    }
    swap(n,m);
}

void con3()
{
    int i,j;
    for(i=1; i<=m; i++)
    {
        for(j=1; j<=n; j++)
        {
            b[m-i+1][j]=a[i][j];
        }
    }

    for(i=1; i<=m; i++)
    {
        for(j=1; j<=n; j++)
            a[i][j]=b[i][j];
        a[i][j]='\0';
    }
}

void con4()
{
    int i,j;
    for(i=1; i<=m; i++)
    {
        for(j=1; j<=n; j++)
        {
            b[i][n-j+1]=a[i][j];
        }
    }

    for(i=1; i<=m; i++)
    {
        for(j=1; j<=n; j++)
            a[i][j]=b[i][j];
        a[i][j]='\0';
    }
}

void con5()
{
    int i,j;
    for(i=1; i<=m; i++)
    {
        for(j=1; j<=n; j++)
        {
            b[j][m-i+1]=a[i][j];
        }
    }

    for(i=1; i<=n; i++)
    {
        for(j=1; j<=m; j++)
            a[i][j]=b[i][j];
        a[i][j]='\0';
    }
    swap(m,n);
}

void con6()
{
    int i,j;
    for(i=1; i<=m; i++)
    {
        for(j=1; j<=n; j++)
        {
            b[n-j+1][i]=a[i][j];
        }
    }

    for(i=1; i<=n; i++)
    {
        for(j=1; j<=m; j++)
            a[i][j]=b[i][j];
        a[i][j]='\0';
    }
    swap(m,n);
}

void debug()
{
    int i,j;
    for(i=1;i<=2;i++)
    {
        for(j=1;j<=2;j++)
            cout<<tb[i][j]<<" ";
        cout<<endl;
    }
}

int main()
{
    int i,j;
    while(~scanf("%d%d",&m,&n))
    {
        for(i=1; i<=m; i++)
            scanf("%s",a[i]+1);

        scanf("%s",str);
        tb[1][1]=1,tb[1][2]=2,tb[2][1]=3,tb[2][2]=4;

        for(i=0; i<strlen(str); i++)
        {
            if(str[i]=='1')
            {
                swap(tb[1][2],tb[2][1]);
            }
            else if(str[i]=='2')
            {
                swap(tb[1][1],tb[2][2]);
            }
            else if(str[i]=='H')
            {
                swap(tb[1][1],tb[2][1]);
                swap(tb[1][2],tb[2][2]);
            }
            else if(str[i]=='V')
            {
                swap(tb[1][1],tb[1][2]);
                swap(tb[2][1],tb[2][2]);
            }
            else if(str[i]>='A'&&str[i]<='C')
            {
                int s=str[i]-'A'+1;
                for(j=0;j<s;j++)
                {
                    swap(tb[2][2],tb[1][2]);
                    swap(tb[1][1],tb[1][2]);
                    swap(tb[1][1],tb[2][1]);
                }
            }
            else if(str[i]>='X'&&str[i]<='Z')
            {
                int s=str[i]-'X'+1;
                for(j=0;j<s;j++)
                {
                    swap(tb[1][1],tb[2][1]);
                    swap(tb[1][1],tb[1][2]);
                    swap(tb[2][2],tb[1][2]);
                }
            }
        }

        //debug();
        //是中心对称,顺时针转,对称转,沿对角线折都是中心对称,所以1 4只能是对角
        if(tb[1][1]==1&&tb[1][2]==2&&tb[2][1]==3&&tb[2][2]==4) {}  // 1 2 3 4
        else if(tb[1][1]==1&&tb[1][2]==3&&tb[2][1]==2&&tb[2][2]==4) con1();  //1 3 2 4
        else if(tb[1][1]==2&&tb[1][2]==1&&tb[2][1]==4&&tb[2][2]==3) con4();  //2 1 4 3
        else if(tb[1][1]==3&&tb[1][2]==1&&tb[2][1]==4&&tb[2][2]==2) con5();  //3 1 4 2
        else if(tb[1][1]==4&&tb[1][2]==2&&tb[2][1]==3&&tb[2][2]==1) con2();  //4 2 3 1
        else if(tb[1][1]==4&&tb[1][2]==3&&tb[2][1]==2&&tb[2][2]==1) {con2(); con1();} //4 3 2 1
        else if(tb[1][1]==2&&tb[1][2]==4&&tb[2][1]==1&&tb[2][2]==3) con6();  //2 4 1 3
        else if(tb[1][1]==3&&tb[1][2]==4&&tb[2][1]==1&&tb[2][2]==2) {con6(); con2();} //3 4 1 2
        cout<<m<<" "<<n<<endl;
        for(i=1; i<=m; i++)
            cout<<a[i]+1<<endl;
    }
    return 0;
}

/*
3 4
0000
a0b0
cdef
A1
*/



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值