矩阵的转置和旋转

转置:

转置很简单的,就是a[i][j] -- > a[j][i]即可。可以开辟一个新的二维数组。b[i][j] = a[j][i]即可。

例题:输入一个N*N的矩阵,将其转置后输出。要求:不得使用任何数组(就地逆置)。

此时应该怎么办呢?只要根据题目要求,直接输出就可以啦!(解释一下,为什么我的输出部分要写成下面这样,把最后一列单独输出出来, 那是因为在大多数的oj上,运行通过的要求是最后一列输出不准存在空格)。

#include<iostream>
using namespace std;
int main(){
	int a[101][101];
	int n;
	while(cin >> n){
		int p, q, i, j;
		for(i = 0; i < n; i ++){
			for(j = 0; j < n; j ++){
				cin >> a[i][j]; 
			}
		}
		for(i = 0; i < n; i ++){
			for(j = 0; j < n - 1; j ++){
				cout << a[j][i] << " "; 
			}
			cout << a[n - 1][i] << endl;
		}
	}
	return 0;
} 

旋转:

我们这里只分析旋转90度之后的矩阵和原矩阵的联系。旋转180, 270之类的可以理解将旋转后的矩阵再旋转n*90即可。

顺时针:


void swap(long long &a, int &b){
	int temp = a;
	a = b;
	b = temp;
}
void rotate1(long long a[][20], int n){// 顺时针。 
		for(int i = 0; i < n; i ++){// 先交换主对角线两端的数即可。 
			for(int j = i; j < n; j ++){
				swap(a[i][j], a[j][i]);
			}
		}
		for(int i = 0; i < n ; i ++){
			for(int j = 0; j < n / 2; j ++){
				swap(a[i][j], a[i][n - 1 - j]);
			}
		}
}

使用一个新开辟的数组:

void rotate1(long long a[][20], int n){// 顺时针 
	int y[20][20];
	for(int i = 0; i < n; i ++){
		for(int j = 0; j < n; j ++){
			y[i][j] = a[n - 1 - j][i];
		}
	}
	for(int i = 0; i < n; i ++){
		for(int j = 0; j < n; j ++){
			a[i][j] = y[i][j];
		}
	}
}

逆时针:


void swap(long long &a, int &b){
	int temp = a;
	a = b;
	b = temp;
}
void rotate1(long long a[][20], int n){// 逆时针。 
		for(int i = 0; i < n; i ++){// 先交换主对角线两端的数即可。 
			for(int j = i + 1; j < n; j ++){
				swap(a[i][j], a[j][i]);
			}
		}
		for(int i = 0; i < n / 2; i ++){
			for(int j = 0; j < n; j ++){
				swap(a[i][j], a[n - 1 - i][j]);
			}
		}
}

开辟新空间直接转换这里就不提供了。(以上使用long long 没有特别的意思, 只是我刚好做的一题中的要求。)


例题:

Give you a nn matrix, if you rotate it 90 degrees, we call it 1-Matrix, if you rotate it 180 degrees, we call it 2-Matrix, etc … This is said if you rotate the Matrix 90k degrees, then we call it k-Matrix. Now, your task is to calculate all the sum of i-Matrix (0<= i<= k).

它的意思是求旋转n次之后左右的矩阵的和,包括自己本身。

分析:1.旋转360度之后是不是又回到了原来的样子,那么我们可以以这4次旋转的和为一个基底,看看一共进行了多少个4,再把多余出来的加上去进行了吧。2.需要加上自己原来输入的这个矩阵,但是显然它在不停的旋转啊,所以就可以定义一个二维数组将它存起来,在开辟一个做存储和的二维数组即可。

参考代码:

#include<iostream>
using namespace std;

void swap(long long &a, int &b){
	int temp = a;
	a = b;
	b = temp;
}
void rotate1(long long a[][20], int n){// 顺时针。 
		for(int i = 0; i < n; i ++){// 先交换主对角线两端的数即可。 
			for(int j = i; j < n; j ++){
				swap(a[i][j], a[j][i]);
			}
		}
		for(int i = 0; i < n ; i ++){
			for(int j = 0; j < n / 2; j ++){
				swap(a[i][j], a[i][n - 1 - j]);
			}
		}
}
int main(){
	int n, m , l, t;
	long long a[20][20], b[20][20], c[20][20];
	while(cin >> n){
		for(int i = 0; i < n; i ++){
			for(int j = 0; j < n; j ++){
				cin >> a[i][j];
				b[i][j] = a[i][j];
				c[i][j] = 0;
			}
		}
		
		rotate1(a, n); 
		cin >> m;
		l = m; m = m / 4;
		for(t = 1; t <= 4; t ++){
			rotate1(a, n);
		    for(int i = 0; i < n; i ++){
			   for(int j = 0; j < n; j ++){
				c[i][j] += a[i][j];
			}
		}	
		}  
		
		for(int i = 0; i < n; i ++){
			for(int j = 0; j < n; j ++){
				c[i][j] = m * c[i][j];
			}
		}
		for(t = 1; t <= l % 4; t ++){
			rotate1(a, n);
			for(int i = 0; i < n; i ++){
			   for(int j = 0; j < n; j ++){
				c[i][j] += a[i][j];
			}
		}		
		}

		for(int i = 0; i < n; i ++){
			for(int j = 0; j < n - 1; j ++){
				cout << c[i][j] + b[i][j]<< " ";
			}
			cout << c[i][n - 1] + b[i][n - 1]<< endl;
		}
	} 
	return 0;
} 


以上就是这篇的所有内容。欢饮您找出错误或者提出改进意见,谢谢!

猜你喜欢

转载自blog.csdn.net/kobe_jr/article/details/80231229
今日推荐