问题描述
最近JOE又在线性代数的模拟考中拿满分了,这直接导致了JOE对于计算矩阵的热情急剧下降,所以JOE希望能有这样一个程序能帮助他计算矩阵的秩。
输入格式
第一行,两个数n,m,表示矩阵是n*m的。
下面共n行,每行m个数(可能为负),表示这个矩阵。
输出格式
这个矩阵的秩。
样例输入
2 3
1 2 1
2 4 3
样例输出
2
数据规模和约定
40% n, m <= 5
70% n, m <= 10
100% n, m <= 20
#include<iostream>
#include<math.h>
using namespace std;
double eps = 1e-8;
double matrix[21][21] = {0};
int n, m;
int find() {
int ans = 0;
for (int i = 0; i < m; i ++) {
int temp = ans;
for (int j = ans; j < n; j ++) {
if (fabs(matrix[j][i]) > fabs(matrix[temp][i])) {
temp = j;
}
}
if (fabs(matrix[temp][i]) < eps) {
continue;
}
for (int j = i; j < m; j ++) {
swap(matrix[ans][j], matrix[temp][j]);
}
for (int j = m - 1; j >= i; j --) {
matrix[ans][j] /= matrix[ans][i];
}
for (int j = ans + 1; j < n; j ++) {
if (fabs(matrix[j][i]) < eps) {
continue;
}
for (int k = m - 1; k >= i; k --) {
matrix[j][k] -= matrix[j][i] * matrix[ans][k];
}
}
ans++;
}
return ans;
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i ++) {
for (int j = 0; j < m; j ++) {
cin >> matrix[i][j];
}
}
cout << find();
return 0;
}
总结:
分4步:
第一步:从第一列开始,找到每行行首的最大值
第二步:将拥有最大行首的那一行和当前一行交换
第三步:将当前行(即已经是最大行首的那一行)的所有数除以行首,也就是将行首的系数变成1
第四步:将当前行后面的其它行都减去当前行的数乘以其他行的行首
解释一下第四步,因为当前行的行首系数已经是1,所以其他行为了减去当前第一列的那排数,就得减去当前行的数乘以自己第一列的那个数
第三步,就是将x(即当前行的第一列)的系数化为1
第四步,即其他行减去第一行乘以自己行的x的系数
即除去x那一列