题目链接:http://acm.swust.edu.cn/problem/643/
Time limit(ms): 1000 Memory limit(kb): 65535
Description
一个n阶方阵A行列式记作detA,或者|A|.detA是一个数字,它的值按照下面的方式递归定义:
如果n=1,detA=a11;
如果n>1,detA= s1 *a11*detA1+s2 * a12 *detA2 +......+sn * a1n *det An
一个上三角矩阵的行列式等于主对角线上元素的乘积。
行列式具有如下的性质:
性质1 行列式的行与列互换,其值不变;
性质2 用数k乘行列式的某一行(列),等于以数乘此行列式
如果n=1,detA=a11;
如果n>1,detA= s1 *a11*detA1+s2 * a12 *detA2 +......+sn * a1n *det An
一个上三角矩阵的行列式等于主对角线上元素的乘积。
行列式具有如下的性质:
性质1 行列式的行与列互换,其值不变;
性质2 用数k乘行列式的某一行(列),等于以数乘此行列式
Input
第一行输入矩阵的阶n
Output
第二行输入矩阵本身。
第二行输入矩阵本身。
n阶矩阵A的行列式detA.
Sample Input
2
1 2
3 4
|
Sample Output
-2 |
hint
用高斯消去法得上三角矩阵
解题思路:并不相信hint了(开个n次方就是x^(1/n),非要说牛顿切线方程,笑哭~~~),利用线性代数中行列式的性质化为上三角(下三角)行列式
我这里化为上三角,然后行列式的值就是对角线乘积~~~~代码有详细注释,实在不会的看现代书吧~~~~
代码如下:
1 #include <stdio.h> 2 double mpt[21][21]; 3 void init(int n) 4 { 5 int row, col; 6 for (row = 0; row < n; row++) 7 for (col = 0; col < n; col++) 8 scanf("%lf", &mpt[row][col]); 9 } 10 11 void solve(int n){ 12 double temp, ans = 1.0; 13 int cnt = 0, flag = 0; 14 //cnt统计行变换 次数,每交换一次行,行列式符号变化1次,统计变化次数(详见线性代数课本) 15 int row, nextrow, col; 16 double tmp; 17 for (row = 0; row < n - 1; row++){ 18 nextrow = row + 1; 19 //开始处理第一列,如果行列式第一行第一个数为零,要交换行 20 if (mpt[row][row] == 0){ 21 while (mpt[nextrow][row] == 0){ 22 nextrow++; //如果行列式第二行第一个数为零,行增加继续寻找非零数值的行 23 //如果遍历完行列式行列式第一列元素都为零,退出while循环 24 if (nextrow == n){ 25 flag = 1; 26 break; 27 } 28 } 29 if (flag)continue; 30 //退出while循环后回到for(row=0;row<n-1;row++)行加1从mpt[row][row]==0知列也相应加1,开始处理第二列 31 cnt++; 32 for (col = 0; col < n; col++){ 33 //交换非零行到行列式顶部 34 tmp = mpt[row][col]; 35 mpt[row][col] = mpt[nextrow][col]; 36 mpt[nextrow][col] = tmp; 37 } 38 } 39 for (nextrow = row + 1; nextrow < n; nextrow++){ 40 temp = mpt[nextrow][row] / mpt[row][row]; 41 for (col = 0; col < n; col++) 42 mpt[nextrow][col] += -temp*mpt[row][col];//化行列式为上三角行列式形式 43 } 44 } 45 for (row = 0; row < n; row++)ans *= mpt[row][row]; 46 printf("%.f ", cnt & 1 ? -ans : ans); 47 } 48 int main(){ 49 int n; 50 scanf("%d", &n); 51 init(n); 52 solve(n); 53 return 0; 54 }