zoukankan      html  css  js  c++  java
  • 行列式计算的两种方法

    #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;
    }
    /*
    4
    3 4 5 11
    2 5 4 9
    5 3 2 12
    14 -11 21 29
    
    4
    2 0 0 0
    0 2 0 0
    0 0 2 0
    0 0 0 2 
    
    2
    1 2 3 4
    */
  • 相关阅读:
    【递推】【HDU 2073】无限的路 (找规律)
    【省赛】山东省第七届ACM省赛(部分水题)
    【思维】牛客练习赛16 B-漂亮的树
    【搜索】牛客练习赛16 C-任意点 (类似求联通块)
    输入输出
    Python入门——运行python的两种方式&变量&常量
    编程语言分类
    What is an Operating System?
    计算机硬件&编程基础
    《SPA设计与架构》之认识SPA
  • 原文地址:https://www.cnblogs.com/hujunzheng/p/4771380.html
Copyright © 2011-2022 走看看