The 45th International College Student Programming Contest Asia Online Regional Competition Simulation Contest I Character Wheels [Simulation]

Portal: Character Wheels

Title

Give you an n*n matrix, and ensure that n is even. There are a total of n/2 layers from the outside to the inside. Now there are m operations. For each operation:

  1. Select one of the layers to turn left (counterclockwise) or right (clockwise) y times.
  2. Output the current matrix.

Ideas

Direct simulation.

  • If you want to output the matrix. For each layer, maintain a linear table in the order of upper left -> upper right -> lower right -> lower left of the matrix. If you need to output a new matrix, traverse the linear table and store the answer matrix according to its corresponding position.
  • If you want to select a layer, rotate it y times. Set num=y%4, if num!=0, rotate to the right num times, which is equivalent to rotate 4-num times to the left. Then update the starting position of each layer in the corresponding linear table.

AC code

#include <bits/stdc++.h>
using namespace std;
const int N=52;
int n,m;
char a[N][N],ans[N][N];
int dir[4][2]={
    
    0,1,1,0,0,-1,-1,0}; // 右、下、左、上
vector<char>g[N]; // 按矩阵的左上->右上->右下->左下的顺序维护一个线性表
int pos[N]; // 记录第i层的首个字符在g[i]中的下标
int main()
{
    
    
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
            cin>>a[i][j];
    int h=n/2; // h层
    for(int i=1;i<=h;i++)
    {
    
    
        pos[i]=0;
        int bx=i;
        int by=i;
        int k=0; // 方向
        int x=bx,y=by;
        while(1)
        {
    
    
            if(k==3&&x==bx&&y==by)break; // 向上回到起点,结束
            g[i].push_back(a[x][y]);
            int d=(h-i+1)*2-1;
            if(k==0&&x==bx&&y==by+d) // 右上角,改变方向
            	k++;
            else if(k==1&&x==bx+d&&y==by+d) // 右下角
                k++;
            else if(k==2&&x==bx+d&&y==by) // 左下角
                k++;
            x+=dir[k][0];
            y+=dir[k][1];
        }
    }
    cin>>m;
    char opt;
    while(m--)
    {
    
    
        cin>>opt;
        int k,num;
        if(opt=='P')
        {
    
    
            for(int i=1;i<=h;i++)
            {
    
    
                int bx=i,by=i;
                int x=bx,y=by;
                int cnt=pos[i];
                int k=0; // 方向
                while(1)
                {
    
    
                    if(k==3&&x==bx&&y==by)break; // 向上回到起点,结束
                    ans[x][y]=g[i][cnt];
                    cnt=(cnt+1)%g[i].size(); // 记得取模
                    int d=(h-i+1)*2-1;
                    if(k==0&&x==bx&&y==by+d) // 右上角,改变方向
                        k++;
                    else if(k==1&&x==bx+d&&y==by+d) // 右下角
                        k++;
                    else if(k==2&&x==bx+d&&y==by) // 左下角
                        k++;
                    x+=dir[k][0];
                    y+=dir[k][1];
                }
            }
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    j==n?printf("%c\n",ans[i][j]):printf("%c",ans[i][j]);
        }
        else
        {
    
    
            cin>>k>>num;
            num%=4;
            if(opt=='R'&&num!=0)num=4-num; // 转换成L
            int d=(h-k+1)*2-1;
            pos[k]=(pos[k]+num*d)%g[k].size();
        }
    }
    return 0;
}

UPDATE 2020.11.1 simplified

In fact, you don't need to put them in the linear table in order, you can directly modify the original matrix, swap 4 positions each time to adjust the order.

#include <bits/stdc++.h>
using namespace std;
const int N=52;
int n,m;
char s[N][N];
void rot(int k,int num) // 第k层左转num次
{
    
    
    int h=n/2; // 共h层
    int d=(h+1-k)*2; // 第k层行(列)的长度
    while(num--)
    {
    
    
        for(int i=1;i<=d-1;i++)
        {
    
    
            int x1=k,y1=k+i-1; // 左上角往右第i个 (x1,y1)
            int x2=k+i-1,y2=k+d-1; // 右上角往下第i个 (x2,y2)
            int x3=k+d-1,y3=k+d-i; // 右下角往左第i个 (x3,y3)
            int x4=k+d-i,y4=k; // 左下角往上第i个 (x4,y4)
            swap(s[x1][y1],s[x2][y2]);
            swap(s[x2][y2],s[x3][y3]);
            swap(s[x3][y3],s[x4][y4]);
        }
    }
}
int main()
{
    
    
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>s[i]+1;
    cin>>m;
    while(m--)
    {
    
    
        char opt;
        cin>>opt;
        if(opt=='P')
        {
    
    
            for(int i=1;i<=n;i++)
                printf("%s\n",s[i]+1);
        }
        else
        {
    
    
            int k,num;
            cin>>k>>num;
            num%=4;
            if(opt=='R'&&num!=0)num=4-num; // 转换成L
            rot(k,num);
        }
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/ljw_study_in_CSDN/article/details/109408786