没用double,用的分数表示。不能算太大的。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#define MAXN 50
#define MOD 1000000007
using namespace std;
struct mat{
int size;
long long mat[MAXN][MAXN];
};
long long eu(long long a, long long b){
if(b==0)
return a;
else
return eu(b,a%b);
}
struct xy{
long long x,y;
xy(long long a,long long b){
x=a;
y=b;
}
xy(void){};
void init(){
long long t=eu(x,y);
x/=t;
y/=t;
x%=(MOD*y);
}
bool zero(){
return x==0;
}
xy mul(xy other){
xy ss;
ss.x=x*other.x;
ss.y=y*other.y;
ss.init();
return ss;
}
void del(xy other){
x=x*other.y;
y=y*other.x;
init();
}
void sub(xy other){
long long tx=x*other.y-other.x*y;
long long ty=other.y*y;
x=tx;
y=ty;
init();
}
};
//矩阵 高斯消元法
long long det(const mat a){
xy b[MAXN][MAXN];
int i,j,k,sign=0;
xy res(1,1);
for( i=0; i<a.size; ++i)
for( j=0; j<a.size; ++j)
{ b[i][j].x=a.mat[i][j]; b[i][j].y=1;}
for( i=0; i<a.size; ++i){
if(b[i][i].zero()){///////////////////////////////////////////////////////过会儿改进
for(j=i+1; j<a.size; ++j)
if(!b[j][i].zero()) break;
if(j==a.size)
return 0;
for(k=0; k<a.size; ++k)
{b[i][k].x^=b[j][k].x^=b[i][k].x^=b[j][k].x; b[i][k].y^=b[j][k].y^=b[i][k].y^=b[j][k].y;}
++sign;
}
res=res.mul(b[i][i]);
for(k=i+1; k<a.size; ++k)
b[i][k].del(b[i][i]);
for(j=i+1; j<a.size; ++j)
for(k=i+1; k<a.size; ++k)
b[j][k].sub(b[j][i].mul(b[i][k]));
}
if(sign&1)
return -res.x/res.y;
else
return res.x/res.y;
}
//
int mem[10000];
int main(){
int n,lim,i,j;
mat a,b;
while(scanf("%d",&n)!=EOF){
a.size=b.size=n;
for(i=0; i<n; ++i)
for(j=0; j<n; ++j)
scanf("%lld",&a.mat[i][j]);
// printf("%lld/n",a.mat[0][0]);
// for(i=0; i<n; ++i)
// for(j=0; j<n; ++j)
// scanf("%d",&b.mat[i][j]);
printf("%lld/n",det(a));
}
}