(模拟)洛谷P4924 [1007]魔法少女小Scarlet

一、算法分析

首先要想到的是,对于矩阵的旋转操作,可以从外到内分一层一层来做,这就把每次矩阵的旋转操作变成了r次边的旋转。此外,交换问题需要设置辅助数组。然后就是一个小trick,在for循环里面加一个t作为位置的辅助变量,可以方便每次的旋转。还有就是自己做这道题的时候,先写了顺时针,写顺时针就调了一段时间,结果想到还要写逆时针,很麻烦。于是突然想到,逆时针等于三次顺时针,于是直接复制前面写好的顺时针代码,完美解决问题。

二、代码及注释

#include
#include
#include
#include
using namespace std;
const int N=550;
int G[N][N];
int w[N];
int n,m;
void init(){
    for(int i=1,t=1;i<=n;i++)
        for(int j=1;j<=n;j++) G[i][j]=t++;
}
void print(){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++) cout<<G[i][j]<<' ';
        cout<<endl;
    }
}
void move(int x,int y,int maxr,int z){
    if(z==0)
        for(int r=1;r<=maxr;r++){
            memset(w,0,sizeof(w));
            for(int i=y-r,t=1;i<=y+r;i++) {w[t++]=G[x-r][i];/*cout<}
            for(int i=x-r,t=y+r;i<=x+r;i++) {G[x-r][t--]=G[i][y-r];/*cout<}
            for(int i=y-r,t=x-r;i<=y+r;i++) {G[t++][y-r]=G[x+r][i];/*cout<}
            for(int i=x+r,t=y-r;i>=x-r;i--) G[x+r][t++]=G[i][y+r];
            for(int i=1,t=x-r;i<=2*r+1;i++) G[t++][y+r]=w[i];
        }
    else{
        for(int k=0;k<3;k++)
            for(int r=1;r<=maxr;r++){
                memset(w,0,sizeof(w));
                for(int i=y-r,t=1;i<=y+r;i++) {w[t++]=G[x-r][i];/*cout<}
                for(int i=x-r,t=y+r;i<=x+r;i++) {G[x-r][t--]=G[i][y-r];/*cout<}
                for(int i=y-r,t=x-r;i<=y+r;i++) {G[t++][y-r]=G[x+r][i];/*cout<}
                for(int i=x+r,t=y-r;i>=x-r;i--) G[x+r][t++]=G[i][y+r];
                for(int i=1,t=x-r;i<=2*r+1;i++) G[t++][y+r]=w[i];
            }
    }
}

int main(){
    
    scanf("%d%d",&n,&m);
    init();
    while(m--){
        int x,y,r,z;
        cin>>x>>y>>r>>z;
        move(x,y,r,z);
    }
    print();
    
    return 0;
    
}

你可能感兴趣的:(模拟)