• TOJ4537: n阶行列式


    4537: n阶行列式 分享至QQ空间

    Time Limit(Common/Java):1000MS/3000MS     Memory Limit:65536KByte
    Total Submit: 28            Accepted:3

    Description

     

    设有n²个数,排列成n行n列的表

        其中p1,p2,p3,...,pn是1到n的一个全排列。标准次序是从小到大。
    注意在这n个元素的任一排列中,当两个元素的先后次序与标准次序不同时,就说有一个逆序,一个排列中所有逆序的总和叫做这个排列的逆序数。逆序数为奇数的排列叫做奇排列,反之为偶排列。τ为当前排列的逆序数。

         

     

     

    Input

     

    每组数据一个n,接下来有n*n个数据。0<n<10。输入直到n为0结束。

    Output

     

    对于每组数据,输出n阶行列式D的值,每组数据后一换行。

     

    Sample Input

     

    2
    3 -2
    2 1
    0

    Sample Output

     case1: D=7.

    Source

    TOJ

    我提供了两种写法,一种是其可以暴力算,但是复杂度还是挺高的

     

    #include<iostream>
    using namespace std;
    __int64 det(__int64 *a, int n)
    {
        int i,j,m,c;
        --n;
        __int64 s=0,b[n*n];
        if(n==0)return a[0];
        for(m=1; m<=n+1; m++)
        {
            c=0;
            for(i=0; i<=n; i++)
                for(j=0; j<=n; j++)
                    if(!(i==0||(j+1)==m))
                        b[c++]=a[i*n+j+i];
            if((m+1)%2)
                s+=-1*a[m-1]*det(b,n);
            else
                s+=a[m-1]*det(b,n);
        }
        return s;
    }
    int main()
    {
        __int64 a[105];
        int ca=1,n,i,j;
        while(cin>>n,n)
        {
            for(i=0; i<n; i++)
                for(j=0; j<n; j++)
                    cin>>a[i*n+j];
            cout<<"case"<<ca++<<": D="<<det(a,n)<<".
    
    ";
        }
        return 0;
    }

     

    化简成上三角行列式的

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    ll a[20][20];
    ll det(int n)
    {
        ll ans=1;
        int sign=0;
        for(int i=0; i<n; i++) //当前行
        {
            for(int j=i+1; j<n; j++) //当前之后的每一行,因为每一行的当前第一个数要转化成0(想想线性代数中行列式的计算)
            {
                int x=i,y=j;
                while(a[y][i])//利用gcd的方法,不停地进行辗转相除
                {
                    ll t=a[x][i]/a[y][i];
                    for(int k=i; k<n; k++)
                        a[x][k]=a[x][k]-a[y][k]*t;
                    swap(x,y);
                }
                if(x!=i)//奇数次交换,则D=-D'整行交换
                {
                    for(int k=0; k<n; k++)swap(a[i][k],a[x][k]);
                    sign^=1;
                }
            }
            if(a[i][i]==0)//斜对角中有一个0,则结果为0
            {
                return 0;
            }
            else
                ans=ans*a[i][i];
        }
        if(sign)ans*=-1;
        return ans;
    }
    int main()
    {
        int ca=1,n,i,j;
        while(cin>>n,n)
        {
            for(i=0; i<n; i++)
                for(j=0; j<n; j++)
                    cin>>a[i][j];
            cout<<"case"<<ca++<<": D="<<det(n)<<".
    
    ";
        }
        return 0;
    }

     

  • 相关阅读:
    jQuery火箭图标返回顶部代码
    易购商城首页
    使用HTML5验证博客园用户注册页面
    正则表达式相关内容和用法
    表单
    jQuery制作图片提示效果
    jQuery遍历
    用js制作论坛发贴
    使用jQuery操作DOM
    京东常见问题分类页面
  • 原文地址:https://www.cnblogs.com/BobHuang/p/9760845.html
Copyright © 2020-2023  润新知