2017年ICPC 四川省赛C题 Determinant

题目描述
C题 Determinat

题目大意
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

猜你喜欢

转载自blog.csdn.net/qq_32352777/article/details/80240064