ACM矩阵行列式计算

来源:互联网 发布:淘宝苹果配件 编辑:程序博客网 时间:2024/04/30 02:29
ACM行列式计算
计算行列式的基本方法就是把矩阵化成上三角或下三角,然后观察对角线的元素,如果其中有个一元素为0则整体为0,否则行列式的值就是对角线上各个元素的乘积。
     先说明一下行列式的几个性质:
 
 
    




    举个例子
        
要将此行列式转化成上三角,根据以上行列式的性质,要将2,3,4行的第一列数字转化成0时,分别要加上第一列的-2/3倍,-3/4倍,-2/3倍;
但是我们不想乘上分数,因为计算机计算的时候会造成一定的精度误差。所以我们采用另一种方式,利用最大公约数(gcd)来讲行列式装换成上三角行列式
        以第一行和第二行为例
3=2*1+1   ------>  2=1*2+0
第一步:
       
如上图前两行,第一步讲3,2根据gcd的3=2*1+1   ------>   2=1*2+0  转化成1,2,此时还没有化成0,继续转化2=1*2+1   ------>   1=1*1+0 讲1,2转化成1,0,转化完成;
检查变化次数,根据上面行列式的性质,如果为偶数次,行列式D=D',如果是奇数次D=-D' 
一二行的第一个数转化好之后,就转化1,3行的,一次类推
给出行列式代码以供参考:

#include<iostream>#include<cstdio>#include<cmath>using namespace std;typedef __int64 lld;lld a[205][205];int sign;lld N,MOD;void solved(){    lld ans=1;    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的方法,不停地进行辗转相除            {                lld t=a[x][i]/a[y][i];                for(int k=i;k<N;k++)                    a[x][k]=(a[x][k]-a[y][k]*t)%MOD;                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        {            cout<<0<<endl;            return ;        }        else            ans=ans*a[i][i]%MOD;    }    if(sign!=0)        ans*=-1;    if(ans<0)        ans+=MOD;    printf("%I64d\n",ans);}int main(){    int t;    scanf("%d",&t);    while(t--)    {        sign=0;        scanf("%I64d%I64d",&N,&MOD);        for(int i=0;i<N;i++)            for(int j=0;j<N;j++)                scanf("%I64d",&a[i][j]);        solved();    }    return 0;}






贴上一个题目:

Game

时间限制(普通/Java) : 5000 MS/ 10000 MS          运行内存限制 : 65536 KByte
总提交 : 23            测试通过 : 6 

描述

   lxhgww feels quite bored these days,so he invented some weird game to kill time."Counting is Easy" is undoubtedly the weirdest,it's played on a N*N chess board.You are supposed to put N rooks on the chess board,and there shouldn't be two these are in the same row or column.There are many different assignment,and it's clear that the exact number is N!,so this is not your task.In this game,there is a positive integer number on each cell of the board,an assignment's value is the product of all the numbers whose cells are occupied by rooks.To make the game more interesting,an assignment may be nagetive or possitive,the sign is decided by the number of "Z Pairs".If there is a pair of rooks in the assignment,and one is on the right-top direction(any angle is accepted) to another,this pair is a Z Pair.If there are odd number of Z Pairs,this assignment is negative,otherwise is positive.The goal of this game is to summarize all the N! assignment's value,don't forget to use minus operation while the assignment is negative.The final answer S is too large to write down,so your task is just to calculate S%P's value.

输入

The first line of input contains an integer T, indicate the number of test cases in the input.Each test case begins with two integer numbers N(where 2<=N<=200) and P(2<=P<=1000000000).The next N lines each contains N integer numbers,which describes the value of each chess board cell,all the numbers are in the range of [0,1000000000].The input is terminated by an invalid test case with N = P = 0, which should not be processed.

输出

For each test case,output one single line contains the answer S%P.

样例输入

1
2 10
4 9
2 8

样例输出

4

提示

    There are two assignments(# means Rook):

 

        *#

        #*

   

        #*

        *#
   

First assignment's value is 2*9=18,and there are one Z-Pair,so it's negative.
   

Second assignment's value is 4*8=32,and there are no Z-pair,so it's positive.
   

So the total value S= -18 + 32 =14,and S%P=14%10=4

So the total value S= -18 + 32 =14,and S%P=14%10=4

题目来源

08年四川省省赛







原创粉丝点击