顺时针旋转矩阵的两种方法

(本来是校赛的水题,没想到我太不给力。。)

Description

一天无聊的DDF在玩弄矩阵:他把矩阵的子矩阵旋转了。

具体来说就是给定一个n*n的初始矩阵,然后DDF每次给出三个数(x,y,r)代表以(x,y)这个点为中心半径为r的子矩阵顺时针旋转90°(注意半径为1即只有(x,y)这个数,建议参考样例佐以理解)。

DDF会给出多次旋转指令,他想知道最后的矩阵会变成什么样子?

Input

输入第一行为矩阵大小n和操作数m

接下来的n行每行n个数为初始矩阵

接下来m行每行3个数(x,y,r)代表一次旋转操作(数据保证不会出现虚空旋转的情况)。

Output

输出经过m次旋转的最终矩阵的样子。

一种是利用全等三角形推出关系

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int m[205][205],sto[205][205];
void solve(int a,int b,int k){
	memcpy(sto,m,sizeof(sto));
	for(int i=a-k;i<=a+k;i++){
		for(int j=b-k;j<=b+k;j++){
			m[j+a-b][b+a-i]=sto[i][j];
		}
	}
}
int main(){
	int n,q; cin>>n>>q;
	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&m[i][j]);
	while(q--){
		int a,b,k; scanf("%d %d %d",&a,&b,&k);
		solve(a,b,k-1);
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			printf("%d ",m[i][j]);
		}
		printf("\n");
	}
	return 0;
} 

另外一种是用不同的遍历方向来做

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
int m[205][205];
queue<int> Q;
void solve(int a,int b,int k){
	for(int i=b-k;i<=b+k;i++){
		for(int j=a-k;j<=a+k;j++){
			Q.push(m[i][j]);
		}
	}
	for(int j=a+k;j>=a-k;j--){
		for(int i=b-k;i<=b+k;i++){
			m[i][j]=Q.front();
			Q.pop();
		}
	}
}
int main(){
	int n,q; cin>>n>>q;
	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&m[i][j]);
	while(q--){
		int a,b,k; scanf("%d %d %d",&a,&b,&k);
		if(k>1) solve(b,a,k-1);
	}
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			printf("%d ",m[i][j]);
		}
		printf("\n");
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/weixin_43191865/article/details/88425995