行列式求值

给一个n×n的矩阵A,请求出detA对p取模后的值。

输入格式:
第一行,两个整数n(1≤n≤200),p(1≤p≤109);
接下来n行,每行n个数,第i+1行第j个数表示Ai,j(0≤|Ai,j|≤109)。
输出格式:
一个数,表示答案。
样例输入:
2 4
5 2
-2 7
样例输出:
3
数据范围:
对于10%的数据,n=2;
另有30%的数据,n≤50;
另有40%的数据,p为质数。
时间限制:
1s
空间限制:
64MB

http://blog.csdn.net/zhoufenqin/article/details/7779707
该博客剖析的透彻,我们是利用矩阵的性质A把它转化成上三角来解决,如果直接除的话要用double,计算机有精度问题,会被卡死,所以我们用类似辗转相除的思想来解决这个问题,注意交换是要将行列式变号的,所以我们就辗转完了之后,看他在不在原来的位置上,若不在,说明换了奇数次,dance抑或1之后换回来就行了,比较水。
试验了一下C++的取余操作,并且重拾了对拍。
计算行列式的基本方法就是把矩阵化成上三角或下三角,然后观察对角线的元素,如果其中有个一元素为0则整体为0,否则行列式的值就是对角线上各个元素的乘积。
具体行列式性质见那篇博客。
行列式的定义是:在一个矩阵中,编号为1-n的行号,列号全排列一个个枚举过去,考虑该排列中逆序对的个数

若为奇,答案加上负的这n个矩阵上对应数的乘积
若为偶,答案加上整的这n个矩阵上对应数的乘积
很像高斯消元但完全不是

//像高斯消元一样的最大公约数算法 
//注意要利用性质,并且swap(x,y),本题卡常,不能一边还一边写 
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
long long A[201][201];
int n;
long long mod;
bool dance=0;
long long ans=1;
int main()
{
    cin>>n>>mod;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=n;j++)
    {
        cin>>A[i][j];
        A[i][j]=A[i][j]%mod;
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=i+1;j<=n;j++)
        {
            int x=i;int y=j;
            while(A[y][i])
            {
                long long t=A[x][i]/A[y][i];
                for(int k=1;k<=n;k++)
                A[x][k]=(A[x][k]-t*A[y][k])%mod;
                swap(x,y);
            }
            if(x!=i)
            {
                dance^=1;
                for(int k=1;k<=n;k++)swap(A[i][k],A[x][k]);
            }
        }
            ans*=A[i][i];
            if(ans==0){puts("0");return 0;}
            ans=ans%mod;
    }
    if(dance) ans=ans*(-1);
    ans=ans%mod;
    ans+=mod;
    ans=ans%mod;
    cout<<ans<<endl;
}
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页