题目描述
题目大意
Bobo学会了ICPCCamp中矩阵A的行列式det(A)的定义。他也知道行列式可以使用高斯消元法在O(n3)中计算。
Bobo有一个n×n矩阵B,他希望为所有的i找到det(Bi,j)对(109 + 7)取模,j∈{1,2,…,n}其中Bi,j是从B中移除第i行和第j列后的矩阵。
输入
输入包含零个或多个测试用例,并由结束符终止。 对于每个测试用例:第一行包含一个整数n。 以下n行中的第i行包含n个整数Bi,1,Bi,2,…,Bi,n。
•2≤n≤500
•0≤Bi,j <109 + 7
•n的总和不超过5000。
输出
对于每种情况,输出n行,其中第i行包含n个整数det(Bi,1),det(Bi,2),…,det(Bi,n)对(109 + 7)取模。
样例输入
0 1
0 1000000006
样例输出
1000000006 0
1 0
解题思路
关于这道题需要知道几个前置知识就是行列式的求解和高斯消元法,不了解的小伙伴可以自行百度学习哦。
对n×n矩阵B的每一个元素求Bi,j,再对Bi,j求行列式 。
java代码
import java.util.Scanner;
public class Determinat {
static double epc=10e9+7;
public static double[][] removal(double a[][],int x,int y){//计算矩阵B移除i行j列所有元素所生成的矩阵
int n=a.length;
double b[][]=new double[n][n],re[][]=new double[n-1][n-1];//n表示原矩阵的阶数,b表示临时矩阵,re表示结果矩阵
for(int i=0;i<n;i++)//复制a矩阵
for(int j=0;j<n;j++)
b[i][j]=a[i][j];
for(int i=x;i<n-1;i++)//行删除
for(int j=0;j<n;j++)
b[i][j]=b[i+1][j];
for(int i=y;i<n-1;i++)//列删除
for(int j=0;j<n-1;j++)
b[j][i]=b[j][i+1];
for(int i=0;i<n-1;i++)//生成结果矩阵
for(int j=0;j<n-1;j++)
re[i][j]=b[i][j];
return re;
}
public static double Det(double Matrix[][],int N) {//计算N阶行列式
double result=0;//结果变量
if(N>=1){
if(N==1)//1阶行列式
return Matrix[0][0];
else if(N==2)//2阶行列式
return (Matrix[0][0]*Matrix[1][1]-Matrix[0][1]*Matrix[1][0])%epc;
else{//N>2阶行列式
for(int T0=0;T0<N;T0++)//将行列式拆分为N个子式
result+=Matrix[0][T0]*Det(removal(Matrix,0,T0),N-1)*Math.pow(-1,T0);
return result%epc;
}
}
return 0;
}
public static void main(String[] args) {
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
double arr[][]=new double[n][n];//变量n表示矩阵阶数,二维数组arr表示n×n阶矩阵
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
arr[i][j]=scan.nextDouble();
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
System.out.printf("%.0f ",Det(removal(arr,i,j),n-1));
System.out.println();
}
}
}
以上代码,纯小编手打,可能有误差,欢迎留言探讨指正。
测试数据
测试1输入:
3
1 2 3
0 1 2
2 1 2
测试2输入:
0 -4 -2
1 -4 -3
1 2 1
测试1输入:
4
1 32 1 2
0 1 2 3
2 4 2 1
12 4 1 1
测试2输入:
-11 -46 -110 -58
24 -33 240 660
-35 -13 1117 749
-129 -6 177 120