行列式求值

来源:互联网 发布:美工海报设计兼职 编辑:程序博客网 时间:2024/04/30 13:48

给一个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;}
原创粉丝点击