P4924 [1007]魔法少女小Scarlet
题解
本题就是一个进行方阵旋转的问题,关键是在于找到顺时针和逆时针变换时的转换公式。
顺时针的话就是:
tmp[j - st_y][k - (i - st_x) - 1] = mat[i][j];
//st_y, st_x是方阵的左上角,相当于一行一行变换,逆时针同理
#include <iostream>
#include <cstdio>
using namespace std;
int mat[502][502] = { 0 };
int tmp[502][502] = { 0 };
void makeMat(int n) //矩阵初始化
{
int count = 1;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
mat[i][j] = count++;
}
}
}
void rotateMat(int x, int y, int r, int z)
{
int k = 2 * r + 1;
if (z == 0)
{
int st_x = x - r; //矩阵左上角
int st_y = y - r; //以st_x, st_y 开始,长宽度均为k的子矩阵
//顺时针旋转相当于把第 i 行 变为 第 k - i + 1 列
for (int i = st_x; i < st_x + k; i++)
{
for (int j = st_y; j < st_y + k; j++)
{
tmp[j - st_y][k - (i - st_x) - 1] = mat[i][j];
}
}
for (int i = st_x; i < st_x + k; i++)
{
for (int j = st_y; j < st_y + k; j++)
{
mat[i][j] = tmp[i - st_x][j - st_y];
}
}
}
else
{
int st_x = x + r; //矩阵右下角
int st_y = y + r; //以st_x, st_y 开始,长宽度均为k的子矩阵
for (int i = st_x; i > st_x - k; i--)
{
for (int j = st_y; j > st_y - k; j--)
{
//tmp[j - st_y][k - (i - st_x) - 1] = mat[i][j];
tmp[st_y - j][k - (st_x - i) - 1] = mat[i][j];
}
}
st_x = x - r; //矩阵左上角
st_y = y - r; //以st_x, st_y 开始,长宽度均为k的子矩阵
for (int i = st_x; i < st_x + k; i++)
{
for (int j = st_y; j < st_y + k; j++)
{
mat[i][j] = tmp[i - st_x][j - st_y];
}
}
}
}
int main()
{
int m, n;
scanf("%d %d", &m, &n);
makeMat(m);
for (int i = 0; i < n; i++)
{
int x, y, r, z;
scanf("%d %d %d %d", &x, &y, &r, &z);
rotateMat(x, y, r, z);
//printf("----------------------------------------------\n");
//printf("----------------------------------------------\n");
}
for (int i = 1; i <= m; i++)
{
for (int j = 1; j <= m; j++)
{
printf("%d ", mat[i][j]);
}
printf("\n");
}
}