Description
已知一个N×N的矩阵A,求A的行列式Mod P的值。
Input
两个整数N、P,然后N*N(N<=200)个整数a[i][j]表示矩阵中第i行j列的数(-1000000001<=a[i][j]<=1000000001)。
Output
一个整数。
Sample Input 1
2 2 2 2 3 4
Sample Output 1
0
【题目分析】
标准的行列式,对于之前不会行列式的我,还是很难的。。。
【运用】
行列式的性质:
1、行列式旋转90度,180度,等等,行列式的值不变
2、任意交换两行或者两列,即在行列式前面加个负号,即D = -D‘
3、特殊的,如果行列式中有两行或者两列相等,行列式的值为0
4、行列式的某一行同乘一个常数k,加到另一行,行列式的值不变
计算行列式
将行列式按照性质变为上三角或者是下三角,行列式的值就等于对角线上的数的乘积
【代码】
#include<cstdio>
#include<iostream>
#define LL long long
using namespace std;
int n;
LL p, a[ 205 ][ 205 ], ans;
void cal(){
int tot = 0;
ans = 1;
for( int i = 1 ; i <= n ; i++ ){
// printf( "%d\n" , i );
for( int j = i + 1 ; j <= n ; j++ ){
// printf( " %d" , j );
int x = i, y = j;
while( a[ y ][ i ] ){ //类似于GCD,将左下三角的数变为0
LL t = a[ x ][ i ] / a[ y ][ i ];
for( int k = i ; k <= n ; k++ )
a[ x ][ k ] = ( a[ x ][ k ] - t * a[ y ][ k ] ) % p;
swap( x, y );
}
if ( x != i ){ //交换两行的值,则D = -D
for( int k = 1 ; k <= n ; k++ )
swap( a[ i ][ k ], a[ x ][ k ] );
// tot = ( tot + 1 ) % 2;
tot = ( tot + 1 ) % 2;
}
}
if ( a[ i ][ i ] == 0 ){
printf( "0\n" );
return;
}
else
ans = ( ans * a[ i ][ i ] ) % p;
// print();
// printf( "%d" , i );
}
if ( tot != 0 )
ans *= -1;
if ( ans < p )
ans += p;
printf( "%lld\n", ans );
}
int main(){
scanf( "%d%lld" , &n, &p );
for( int i = 1 ; i <= n ; i++ )
for( int j = 1 ; j <= n ; j++ ){
scanf( "%lld" , &a[ i ][ j ] );
a[ i ][ j ] %= p;
}
// print();
cal(); //计算行列式的值
return 0;
}