标签:模拟
题目
题目描述
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\leq n,m\leq500\),满足\(1\leq x-r\leq x+r\leq n,1\leq y-r\leq y+r\leq n\)
题解
简单的pj组模拟题,洛谷月赛良心题qwq(打波广告就逃)
每次模拟旋转就好了
平面直角坐标系中坐标旋转变化公式
- 顺时针:\((x,y)->(y,-x)\)
- 逆时针:\((x,y)->(-y,x)\)
code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,a,b) for(int i=a;i>=b;i--)
#define ll long long
#define mem(x,num) memset(x,num,sizeof x)
#define reg(x) for(int i=last[x];i;i=e[i].next)
using namespace std;
inline ll read(){
ll f=1,x=0;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
//******head by yjjr******
const int maxn=3e3+6;
int b[maxn][maxn],a[maxn][maxn],n,m;
void Move(int x,int y,int r,int z){
if(z==0)
rep(i,x-r,x+r)rep(j,y-r,y+r){
int nx=i-x,ny=j-y;
b[x+ny][y-nx]=a[i][j];
}
else rep(i,x-r,x+r)rep(j,y-r,y+r){
int nx=i-x,ny=j-y;
b[x-ny][y+nx]=a[i][j];
}
rep(i,x-r,x+r)rep(j,y-r,y+r)a[i][j]=b[i][j];
}
int main(){
n=read(),m=read();
rep(i,1,n)rep(j,1,n)a[i][j]=n*(i-1)+j;
rep(i,1,m){
int x=read(),y=read(),r=read(),z=read();
Move(x,y,r,z);
}
rep(i,1,n){rep(j,1,n)cout<<a[i][j]<<' ';cout<<endl;}
return 0;
}