Write programs that do one thing and do it well

                                                                                     -----  Doug McIlroy (UNIX哲学)

 

 

如果你学过线代, 又恰巧你是个coder, 那么你应该写个计算行列式的program。

计算行列式(数学知识): 

                每行都按行坐标排序, 求出列坐标排列的逆序数

                根据逆序数的奇偶行判断该项的正负(奇负, 偶正)

                逐项求和。

说明: 输入行列式的 行(列)数 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;
}
View Code

相关文章:

  • 2022-12-23
  • 2021-07-29
  • 2021-11-25
  • 2022-02-01
  • 2021-10-11
  • 2021-06-14
  • 2022-02-26
猜你喜欢
  • 2021-10-28
  • 2022-12-23
  • 2021-07-04
  • 2021-08-23
  • 2021-08-05
  • 2021-12-04
  • 2021-11-25
相关资源
相似解决方案