P4924 [1007]魔法少女小Scarlet
题目描述
\(Scarlet\)最近学会了一个数组魔法,她会在\(n∗n\)二维数组上将一个奇数阶方阵按照顺时针或者逆时针旋转90°,
首先,\(Scarlet\)会把1到\(n^2\)的正整数按照从左往右,从上至下的顺序填入初始的二维数组中,然后她会施放一些简易的魔法。
\(Scarlet\)既不会什么分块特技,也不会什么\(Splay\)套\(Splay\)(本弱也不会),她现在提供给你她的魔法执行顺序,想让你来告诉她魔法按次执行完毕后的二维数组。
输入格式
第一行两个整数\(n,m\)表示方阵大小和魔法施放次数。
接下来\(m\)行,每行4个整数\(x,y,r,z\)表示在这次魔法中,\(Scarlet\)会把以第\(x\)行第\(y\)列为中心的\(2r+1\)阶矩阵按照某种时针方向旋转,其中\(z=0\)表示顺时针,\(z=1\)表示逆时针。
输出格式
输出\(n\)行,每行\(n\)个用空格隔开的数,表示最终所得的矩阵
输入输出样例
输入 #1
5 4
2 2 1 0
3 3 1 1
4 4 1 0
3 3 2 1
输出 #1
5 10 3 18 15
4 19 8 17 20
1 14 23 24 25
6 9 2 7 22
11 12 13 16 21
说明/提示
对于50%的数据,满足\(r=1\)
对于100%的数据\(1≤n,m≤500\),满足\(1≤x−r≤x+r≤n,1≤y−r≤y+r≤n\)
思路
简单说一下思路:暴力!!!
总之就是暴力
转就完事了
思路部分结束
矩阵旋转
顺时针
先进行上下颠倒,然后交换对角线
逆时针
先进行左右互换,再交换对角线
蒟蒻の代码
#include<iostream>
#include<cstdio>
#define maxn 550
using namespace std;
inline int read()//快读
{
char ch;
int fu=1,in=0;
ch=getchar();
while(ch!='-'&&(ch>'9'||ch<'0'))
{
ch=getchar();
}
if(ch=='-')fu=-1;
else in*=10,in+=ch-'0';
ch=getchar();
while(ch>='0'&&ch<='9')
{
in*=10;
in+=ch-'0';
ch=getchar();
}
return in*fu;
}
int n,m;//矩阵大小和操作数
int a[maxn][maxn];//矩阵
inline void output()//输出矩阵
{
for(register int i=1;i<=n;++i)
{
for(register int j=1;j<=n;++j)
{
printf("%d ",a[i][j]);
}
puts("");
}
}
inline void solve(int x,int y,int r,int z)
{
if(r==0)return;//一阶矩阵不需要转
int rr=(r<<1)+1;//旋转矩阵阶数
if(z)//逆时针
{
for(register int i=1;i<=rr;++i)//左右互换
{
for(register int j=1;j<=r;++j)//只需要遍历左半边,因为右边也顺便用过了,中间一列不会交换
{
int tmp=a[x-r+i-1][y-r+j-1];
a[x-r+i-1][y-r+j-1]=a[x-r+i-1][y+r-j+1];
a[x-r+i-1][y+r-j+1]=tmp;
}
}
//output();
//puts("");
for(register int i=2;i<=rr;++i)//对角线交换,画图便知第一行根本不会发生交换a[1][1]->a[1][1]
{
for(register int j=1;j<i;++j)//同理只遍历左下
{
int tmp=a[x-r+i-1][y-r+j-1];
a[x-r+i-1][y-r+j-1]=a[x-r+j-1][y-r+i-1];
a[x-r+j-1][y-r+i-1]=tmp;
}
}
}
else{//顺时针旋转
for(register int i=1;i<=r;++i)//上下颠倒
{
for(register int j=1;j<=rr;++j)//同理只需遍历上半边
{
int tmp=a[x-r+i-1][y-r+j-1];
a[x-r+i-1][y-r+j-1]=a[x+r-i+1][y-r+j-1];
a[x+r-i+1][y-r+j-1]=tmp;
}
}
//output();
//puts("");
for(register int i=2;i<=rr;++i)//对角线交换
{
for(register int j=1;j<i;++j)
{
int tmp=a[x-r+i-1][y-r+j-1];
a[x-r+i-1][y-r+j-1]=a[x-r+j-1][y-r+i-1];
a[x-r+j-1][y-r+i-1]=tmp;
}
}
}
//output();
//puts("");
return;
}
int main()
{
n=read(),m=read();
int k=1;
for(register int i=1;i<=n;++i)//填充矩阵
{
for(register int j=1;j<=n;++j)
{
a[i][j]=k;
k++;
}
}
while(m--)//转起来
{
int x=read(),y=read(),r=read(),z=read();
solve(x,y,r,z);
}
output();
return 0;
}