算法刷题记录:P4924 [1007]魔法少女小Scarlet

题目链接

https://www.luogu.com.cn/problem/P4924

视频链接

https://www.bilibili.com/video/BV1sL411N7cb?vd_source=0bfa84bd4dad23218c3bbb5095b6c764

题目分析

这道题不是我自己写出来的,这个思路很受用!

题意为将以[x,y]为中心某个矩阵,逆时针/顺时针旋转。
所以其本质就是矩阵的旋转,所以找出通项公式即可。
通项公式:
顺时针:x后=x+y-y原,y后=y-x+x原
逆时针:x后=x-y+y原,y后=x+y-x原

AC代码

// Problem: P4924 [1007]魔法少女小Scarlet
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P4924
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <iostream>

const int MAXN = 505;

int n, m, x, y, r, z, cnt;
int w[MAXN][MAXN];

void generate(int x, int y, int r, int z)
{
	int b[MAXN][MAXN];
	for (int i = x - r; i <= x + r; ++ i)
		for (int j = y - r; j <= y + r; ++ j)
			if (!z) b[i][j] = w[x + y - j][y - x + i];
			else b[i][j] = w[x - y + j][x + y - i];
			
	for (int i = x - r; i <= x + r; ++ i)
		for (int j = y - r; j <= y + r; ++ j)
			w[i][j] = b[i][j];
}

int main()
{
	std::cin>> n >> m;
	for (int i = 1; i <= n; ++ i)
		for (int j = 1; j <= n; ++ j)
			w[i][j] = ++ cnt;
					
	for (int i = 0; i < m; ++ i){
		std::cin >> x >> y >> r >> z;
		generate(x, y, r, z);
	}
	for (int i = 1; i <= n; ++ i){
		for (int j = 1; j <= n; ++ j)
			std::cout << w[i][j] << ' ';
		std::cout << std::endl;
	}
}
posted @ 2023-06-10 16:55  想个昵称好难ABCD  阅读(60)  评论(0编辑  收藏  举报