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

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

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;
} 

 

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值