#define LL __int64
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 100; // 矩阵的最大行和列
const int MOD = 1e5; // 如果可以不用取模,则尽量不用
const double eps = 1e-6; // 处理细小的精度问题
const double pi = acos(-1.0); // 圆周率
class Mat
{
public:
int n, m;
double mat[MAXN][MAXN];
Mat()
{
memset(mat, 0, sizeof(mat));
n = m = MAXN - 1;
};
void init() // 初始化为单位矩阵
{
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
mat[i][j] = (i == j);
}
Mat operator * (Mat b) // 重载乘法
{
Mat c;
c = Mat();
c.n = n;
c.m = b.m;
for (int i = 1; i <= n; ++i) // 注意这里从1开始
for (int j = 1; j <= b.m; ++j)
{
//if(mat[j][i] <= 0) continue; // 剪枝
for (int k = 1; k <= m; ++k)
{
//if(b.mat[i][k] <= 0) continue; // 剪枝
//c.mat[i][j] += (mat[i][k] * b.mat[k][j]) % MOD;
//c.mat[i][j] %= MOD;
c.mat[i][j] += mat[i][k] * b.mat[k][j];
}
}
return c;
}
Mat operator + (Mat b) // 重载加法
{
Mat c;
c.n = n;
c.m = m;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
c.mat[i][j] = mat[i][j] + b.mat[i][j];
return c;
}
Mat QuickPow(Mat a, int k) // 快速幂
{
Mat c;
c.n = a.n;
c.m = a.n;
c.init(); // 初始化为单位矩阵
while (k)
{
if (k & 1)//化为二进制然后看1 的个数
c = c*a;
a = a*a;
k >>= 1;
}
return c;
}
Mat transpose() // 求矩阵的转置
{
Mat c;
c.n = m;
c.m = n;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
c.mat[j][i] = mat[i][j];
/*for(int i=1,j=m; i<j; ++i,--j) // 如果加上这里的代码的话,就是矩阵旋转本身
for(int k=1; k<=n; ++k)
{
int tmp = c.mat[k][i];
c.mat[k][i] = c.mat[k][j];
c.mat[k][j] = tmp;
}*/
return c;
}
Mat slove(Mat init, int k) // 递归二分求解递增幂次和
{
if (k == 1)
return init;
Mat c;
c.n = init.n;
c.m = init.m;
c = slove(init, k >> 1);
c = c + c * init.QuickPow(init, k >> 1);
if (k & 1)
return c + init.QuickPow(init, k);
else
return c;
}
void translate(Mat &a, double x, double y, double z) // 平移(三维)
{
Mat c;
c.init();
c.mat[1][4] = x;
c.mat[2][4] = y;
c.mat[3][4] = z;
a = c * a;
}
void scale(Mat &a, double x, double y, double z) // 缩放(三维)
{
Mat c;
c.init();
c.mat[1][1] = x;
c.mat[2][2] = y;
c.mat[3][3] = z;
a = c * a;
}
void rotat(Mat &a, double x, double y, double z, double d) // 旋转(三维),以(0,0,0),(x,y,z)线段为旋转轴,旋转d度
{
d = d / 180 * pi;
double di = sqrt(x*x + y*y + z*z); // 单位化
x /= di, y /= di, z /= di;
Mat c;
c.init();
c.mat[1][1] = (1 - cos(d))*x*x + cos(d);
c.mat[1][2] = (1 - cos(d))*x*y - z*sin(d);
c.mat[1][3] = (1 - cos(d))*x*z + y*sin(d);
c.mat[2][1] = (1 - cos(d))*x*y + z*sin(d);
c.mat[2][2] = (1 - cos(d))*y*y + cos(d);
c.mat[2][3] = (1 - cos(d))*y*z - x*sin(d);
c.mat[3][1] = (1 - cos(d))*x*z - y*sin(d);
c.mat[3][2] = (1 - cos(d))*y*z + x*sin(d);
c.mat[3][3] = (1 - cos(d))*z*z + cos(d);
a = c * a;
}
void in(int x, int y) // 输入矩阵
{
n = x;
m = y;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= m; ++j)
cin>>mat[i][j];
}
void out() // 输出矩阵
{
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
cout<< mat[i][j];
puts("");
}
}
double getvalue()
{
if (n != m)
{
cout << "无法计算行列式" << endl;
return 0;
}
if (n == 1)
{
return mat[1][1];
}
Mat c;
double res=0;
c.m = c.n = n - 1;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n - 1; j++)
for (int k = 1; k <= n - 1; k++)
c.mat[j][k] = mat[j + 1][(k >=i) ? (k + 1) : k];
double tmp= c.getvalue();
if (i % 2 == 0)
res += tmp*mat[1][i];
else
res -= tmp*mat[1][i];
}
return res;
}
Mat company()
{
Mat res;
res.m = res.n = n ;
if (n != m)
{
cout << "无法计算伴随矩阵" << endl;
return res;
}
if (n == 1)
{
res.mat[1][1] = 1;
return res;
}
Mat tmp;
tmp.m = tmp.n = n - 1;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
for (int k = 1; k <= n - 1; k++)
for (int t = 1; t <= n - 1; t++)
tmp.mat[k][t] = mat[(k >= i) ? (k + 1) : k][(t >= j) ? (t + 1) : t];
res.mat[j][i] = tmp.getvalue();
if ((i+j)%2==1)
res.mat[j][i] = -tmp.getvalue();
}
return res;
}
Mat convert()
{
double value = this->getvalue();
Mat res = this->company();
res.m = res.n = n;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
res.mat[i][j] /= value;
return res;
}
};