行列式计算(编程实现)

开始学线性代数啦, 当然作为学软件的,学数学就是要用数学的。 再说还有这么的作业要写,写个小程序岂不是很省力。

说明: 输入行列式的 行(列)数 N

并依次输入n*n个数。 程序将输出

行列式的计算算式,并得出结果!

代码实现分析: 调用头文件<algorithm>里的库函数 next_permutation()  具体实现细节详见代码。

用线段树求逆序数时间复杂度为N*logN。 当然以这种时间复杂度的算法还有树状数组求逆序数, 归并排序求逆序数。

当然你也可以用直接暴力的方法求出逆序数,代码是十分简单的。时间复杂度和插入排序相同n*n。

然后就是具体的一些实现细节啦!

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;

void PushUp(int cur, int *sum)
{
    sum[cur] = sum[cur<<1]+sum[cur<<1|1];
}

void Build(int l, int r, int cur, int *sum)
{
    sum[cur] = 0;
    if(l==r) return ;
    int m = (l+r)>>1;
    Build(l, m, cur<<1, sum);
    Build(m+1, r, cur<<1|1, sum);
}

void Update(int p, int l, int r, int cur, int *sum)
{
    if(l==r)
    {
        sum[cur]++;
        return;
    }
    int m = (l+r)>>1;
    if(p<=m) Update(p, l, m, cur<<1, sum);
    else Update(p, m+1, r, cur<<1|1, sum);
    PushUp(cur, sum);
}
int Query(int L, int R, int l, int r, int cur, int *sum)
{
    if(L<=l&&r<=R)
    {
        return sum[cur];
    }
    int m = (l+r)>>1;
    int ret = 0;
    if(L<=m) ret+=Query(L, R, l, m, cur<<1, sum);
    if(R>m) ret+=Query(L, R, m+1, r, cur<<1|1, sum);
    return ret;
}

int Reverse(int n, int *p)
{
    int sum[n<<2];
    Build(0, n-1, 1, sum);
    int tot = 0;
    for(int i=0; i<n; i++)
    {
        tot+=Query(p[i], n-1, 0, n-1, 1, sum);
        Update(p[i], 0, n-1, 1, sum);
    }
    return tot;
}

void solve(int n, int a[15][15])
{
    int flag = 0;
    long long ans=0;
    int p[15];
    for(int i=0; i<n; i++)
    p[i] = i+1;
    do
    {
        int ok = Reverse(n, p);
        if(ok&1)
        {
            flag++;
           printf(" - ");
            long long temp=1;
            for(int j=1, i=0; i<n; j++, i++)
            {
                temp*=(long long)a[j][p[i]];
                if(j!=1)printf(" * ");
                printf("%d", a[j][p[i]]);

            }
            ans-=temp;
        }
        else
        {
           if(flag)printf(" + ");
           flag++;
             long long temp=1;
            for(int j=1, i=0; i<n; j++, i++)
            {
                temp*=(long long)a[j][p[i]];
                if(j!=1)printf(" * ");
                printf("%d", a[j][p[i]]);
            }
            ans+=temp;
        }
    }while(next_permutation(p, p+n));
    printf("\n%d\n\n", ans);
}

int main() {
  int n;
  int a[15][15];
  while(scanf("%d", &n)!=EOF)
  {
      for(int i=1; i<=n; i++)
      for(int j=1; j<=n; j++)
      scanf("%d", &a[i][j]);
    solve(n, a);
  }
  return 0;
}

PS: 上述程序求解的整型的行列式, (因为课本里的行列式都是整型的,小恪偷了个懒!), 对于其他类型的, 可以定义一个模板! 或者直接把整型的改成实数型。

时间: 2024-12-28 12:22:45

行列式计算(编程实现)的相关文章

MyMathLib系列(行列式计算3)

到今天,行列式和线性方程组部分就完成了. using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace MyMathLib { /// <summary> /// 行列式计算,本程序属于MyMathLib的一部分,欢迎使用,参考,提意见. /// 有时间用函数语言改写,做自己得MathLib,里面的算法经过验证,但没经过 /// 严格测试,如需参考,请慎重. ///

行列式计算(C#)

最近几天学习高等代数老师说要写个程序算行列式的结果,闲来无事就简单写了一下. 不多说了,上代码 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace Nrow_culmn 7 { 8 class Program 9 { 10 public static double jlength = 0; 11 static void Main(st

MyMathLib系列(行列式计算)

靠人不如靠己,准备做自己得MathLib: /// <summary> /// 行列式计算,本程序属于MyMathLib的一部分,欢迎使用,参考,提意见. /// 有时间用函数语言改写,做自己得MathLib,里面的算法经过验证,但没经过 /// 严格测试,如需参考,请慎重. /// </summary> public static partial class LinearAlgebra { /// <summary> /// 求逆序数 /// </summary

MyMathLib系列(行列式计算2)

/// <summary> /// 行列式计算,本程序属于MyMathLib的一部分,欢迎使用,参考,提意见. /// 有时间用函数语言改写,做自己得MathLib,里面的算法经过验证,但没经过 /// 严格测试,如需参考,请慎重. /// </summary> public static partial class LinearAlgebra { /// <summary> /// 获取指定i,j的余子式 /// </summary> /// <pa

Flink流计算编程--在WindowedStream中体会EventTime与ProcessingTime

一.Flink流处理简介 Flink流处理的API叫做DataStream,可以在保证Exactly-Once的前提下提供高吞吐.低延时的实时流处理.用Flink作为流处理框架成功的案例可参考Flink母公司–Data Artisans官方blog中的2篇文章: How we selected Apache Flink as our Stream Processing Framework at the Otto Group Business Intelligence Department RBE

MyMathLib系列(行列式计算4--向量部分)

1)将向量组进行消元,变换成阶梯矩阵,这是求向量组的极大线性无关组的基本算法.这个方法在前面曾经给出过,但在这里做了改进,目的是为了可以判断是否线性相关: /// <summary> /// 方程组消元,最后一列为系数,结果就在CoefficientDeterminant里. /// 本算法也可以用来求矩阵的秩. /// </summary> /// <param name="CoefficientDeterminant">方程组系数数组</p

行列式计算的两种方法

#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个元

Flink流计算编程--在双流中体会joinedStream与coGroupedStream

一.joinedStream与coGroupedStream简介 在实际的流计算中,我们经常会遇到多个流进行join的情况,Flink提供了2个Transformations来实现. 如下图: 注意:Join(Cogroups) two data streams on a given key and a common window.这里很明确了,我们要在2个DataStream中指定连接的key以及window下来运算. 二.SQL比较 我们最熟悉的SQL语言中,如果想要实现2个表join,可以

python 行列式计算

N=2 #声明2x2的数组arr并将所有元素赋值为 None arr=[[None] * N for row in range(N)] print('|a1 b1|') print('|a2 b2|') arr[0][0]=input('请输入a1:') arr[0][1]=input('请输入b1:') arr[1][0]=input('请输入a2:') arr[1][1]=input('请输入b2:') #求二阶行列式的值 result = int(arr[0][0])*int(arr[1]