矩阵行列式
矩阵行列式是代表这个矩阵的一个值,最后的结果是一个数字,运算法则如下
首先最简单的是二维数组
jz[1][1] jz[1][2]
jz[2][1] jz[2][2]
其结果就是对角线相乘相减,即jz[1][1]jz[2][2]-jz[1][2]jz[2][1]
其余的高阶矩阵计算如下:
任一行(或一列)的值逐个乘上它的子矩阵的值并进行加减法
举个例子
因此以三阶矩阵(这次运用第一行)为例
a1 b1 c1
a2 b2 c2
a3 b3 c3
行列式值sum=a1*a1的子矩阵-a2*a2的子矩阵+a3*a3的子矩阵
先说明加减法的规则:
比如说a1是第一行第一列,那么就是(-1)^(1+1)=1,因此是加
a2是第二行第一列,那么就是(-1)^(2+1)=-1,因此是减
那么再来说明什么是子矩阵
子矩阵就是把去掉当前值所在的行和列剩余的矩阵
例如a1的子矩阵就是去掉第一行和第一列后剩余子矩阵的行列式的值
a2的子矩阵就是去掉第二行和第一列后剩余子矩阵的行列式的值
a2的子矩阵如下
a1 c1
a3 c3
那么知道了运算法则的时候,如何简便的运算呢
矩阵计算有以下性质:
1.交换任意两行(或两列)的值,矩阵行列式的值为原数的相反数。
2.任意一行(或一列)加上任意另外一行(或一列)的值乘k(k是任意值),矩阵行列式的值不变(以上面二维行列式举例子)
jz[1][1] jz[1][2]
jz[2][1] jz[2][2]
和
jz[1][1]+jz[2][1]*k jz[1][2]+jz[2][2]*k
jz[2][1] jz[2][2]
算出来的矩阵行列式的值相同
因此以四阶矩阵(这次运用第一行)为例
a1 b1 c1 d1
a2 b2 c2 d2
a3 b3 c3 d3
a4 b4 c4 d4
行列式值sum=a1*a1的子矩阵-a2*a2的子矩阵+a3*a3的子矩阵-a4*a4的子矩阵
我们可以运用第二条将第2,3,4行加上一定倍数的第一行的话将a2,a3,a4的值变为0的话,那么sum=a1*a1的子矩阵
a1的子矩阵为
b2 c2 d2
b3 c3 d3
b4 c4 d4
同理,如果我们将b3,b4的值变为0的话,a1的子矩阵的值=b2*b2的子矩阵的值
。。。
所以只要将矩阵变为
x1 aa bb cc
0 x2 dd ee
0 0 x3 ff
0 0 0 x4
矩阵行列式sum=x1*x2*x3*x4
特别的,如果对角线上的值为0的话,就在开头时将一行与这一行进行交换运用第一个运算规律,使得对角线上的值不为0再进行当前行刷0操作
所以矩阵用double定义,代码如下
#include<bits/stdc++.h>
using namespace std;
#define NU 205
typedef int rt;
inline rt read(){
register char ch=getchar();register rt u=0,sign=1;
while(!isdigit(ch)){if(ch=='-')sign=0;ch=getchar();}
while(isdigit(ch)){u=(u*10)+(ch-48);ch=getchar();}
return sign?u:-u;
}
double sum;//结果
int n;//行列数
int num;//记录交换次数,最后转换正负
double jz[NU][NU]; //double,后面有除法
inline void init();
inline bool text();
inline void work();
inline void out();
void jzswap(int a,int b,int m)
{
for(int i=1;i<=m;++i)
swap(jz[a][i],jz[b][i]);
return;
}
int main()
{
init();
work();
out();
return 0;
}
inline void init()
{
n=read();
for(int i=1;i<=n;++i)
for(int j=1;j<=n;++j)
jz[i][j]=read();
return;
}
inline void work()
{
sum=1.0;
for(int i=1;i<=n;++i)
{
if(jz[i][i]==0) //保证对角线的值不为0
for(int k=i+1;k<=n;++k)
{
if(jz[k][i]!=0)
{
jzswap(i,k,n);
num++;
break;
}
}
for(int k=i+1;k<=n;++k)
{
if(jz[k][i]!=0)
{
double y=jz[k][i]/jz[i][i]; //计算出需要乘的系数值,运算法则2中k的值
for(int l=i;l<=n;++l)
jz[k][l]-=jz[i][l]*y; //将该列的对角线一下的值刷0,改行其余值跟着改变
}
}
}
for(int i=1;i<=n;++i)
sum*=jz[i][i]; //对角线相乘得到结果
if(num%2) sum=-sum; //运算法则1,交换次数为奇数则正负号变换
return;
}
inline void out()
{
printf("%d\n",(int)sum); //记住转int
return;
}