行列式计算的两种方法


#include<iostream> 
#include<cstring>
#include<cstdio>
#include<algorithm>
#define N 100 
using namespace std;
int a[N][N];
double aa[N][N];
int n;

/**********************************************************/
//求行列式的值:是所有取自不同行不同列的n个元素的乘积 
int d[N];
int tmpd[N]; 
int dd[N];
int vis_column[N];//是否在同一列 
int inverse;//逆序数的个数 
int ans = 0;
void merger(int ld, int rd){
    if(ld >= rd) return;
    int mid=(ld+rd)>>1;
    merger(ld,mid);
    merger(mid+1, rd);
    int i=ld, j=mid+1, k=0;
    while(i<=mid && j<=rd){
        int col1 = (tmpd[i]-1)%n+1;
        int col2 = (tmpd[j]-1)%n+1;
        if(col1 < col2){
            dd[++k] = tmpd[i++];
        } else {
            dd[++k] = tmpd[j++];
            inverse += mid-i+1; 
        }
    }
    while(i<=mid) dd[++k] = tmpd[i++];
    while(j<=rd) dd[++k] = tmpd[j++];
    memcpy(tmpd+ld, dd+1, sizeof(int)*(k));
}

void determinantValue(int row){
    if(row>n){
        inverse=0; 
        int tmp = 1;
        for(int k=1; k<=n; ++k){
            int i = (d[k]-1)/n+1;
            int j = (d[k]-1)%n+1;
            tmp *= a[i][j];
        }
        memcpy(tmpd, d, sizeof(int)*(n+1));
        merger(1, n);
        if(inverse&1) ans-=tmp;
        else ans+=tmp;
        return;
    }
    for(int col=1; col<=n; ++col)
        if(!vis_column[col]){
            vis_column[col]=1;
            d[row] = (row-1)*n + col;
            determinantValue(row+1);
            vis_column[col]=0;
        }
}
/**********************************************************/

/**********************************************************/
//以列主元方法,将行列式转变成上三角矩阵

double determinantValueA(){
    int sign = 1;
    double ret = 0.0;
    for(int i=1; i<=n; ++i){
        double maxVal = aa[i][i];
        int j = i;
        for(int k=i+1; k<=n; ++k)//寻找这一列中的元素值的最大值 
            if(maxVal < aa[k][i]){
                maxVal = aa[k][i];
                j = k;
            }
        if(j!=i){
            sign = -sign;
            for(int k=1; k<=n; ++k){//交换两行 
                double tmp = aa[i][k];
                aa[i][k] = aa[j][k];                 
                aa[j][k] = tmp;
            }
        }
        if(maxVal < 1e-10)//最大值为0,也就是意味这对角线上的元素有0出现 
            return ret;
            
        for(int k=i+1; k<=n; ++k){
            double b = aa[k][i]/aa[i][i];
            for(int c=1; c<=n; ++c) 
                aa[k][c] -= b*aa[i][c];
        }
    }
    ret = 1.0;
    for(int i=1; i<=n; ++i)
        ret*=aa[i][i];
    return ret;
}
 
/**********************************************************/
int main() {
//    cin>>n;
//    for(int i=1; i<=n; ++i)
//        for(int j=1; j<=n; ++j)
//            cin>>a[i][j];
//    determinantValue(1);
//    cout<<ans<<endl;
    
    cin>>n;
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=n; ++j)
            cin>>aa[i][j];
    cout<<determinantValueA()<<endl;
    return 0;
}
/*
3 4 5 11
5 4 9
3 2 12
-11 21 29
2 0 0 0
2 0 0
0 2 0
0 0 2 
1 2 3 4
*/

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值