#include<stdio.h>
#include<windows.h>
int main()
{
//1.定义所需求逆矩阵的原矩阵a及其同阶单位矩阵b
int m;float temp,temp2; //像temp这种都是后续写代码发现需要才加的,所以这里先知道m为方阵阶数便好
scanf("%d",&m);
float a[m][m];float b[m][m]; //默认a为方阵,否则没什么实际意义,b为同阶单位矩阵
for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
{
scanf("%f",&a[i][j]);
}
}
printf("\n"); //分开输入a与b,方便观感
for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
{
scanf("%f",&b[i][j]); //这里要规范输入b
}
}
printf("\n");
printf("a:\n");
for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
{
printf("%f ",a[i][j]);
if(j==m-1) printf("\n");
}
}
//2.接下来对a和b进行相同初等行变换
/*我们按照化阶梯型的方式往下走,这样需要首先判断各行第一个元素,不能让第一行第一个
元素为0,否则没办法往下话,而且各行第一个元素不会都是0,否则行列式为0,不可逆,但我们这里也进行判断*/
if(a[0][0]==0)
{
for(int i=1;i<m;i++) //循环判断各行第一个元素是否为0,只要不是,就与第一行交换,同时结束循环
{
if(a[i][0]!=0) //接下来需要考虑如何用代码实现交换行,封装函数操作的话或许让整体代码更简洁,但形参与实参我学的不太好,怕出错,这里选笨方法
{
for(int j=0;j<m;j++) //需要操作m次
{
temp=a[0][j];
a[0][j]=a[i][j];
a[i][j]=temp;
temp=b[0][j]; //别忘了对b操作
b[0][j]=b[i][j];
b[i][j]=temp;
}
break; //这里记得跳出循环
}
}
}
//接下来先化第一列元素为0,除了第一个元素,稍加考虑便知道这里需要二重嵌套循环
/*for(int i=1;i<m;i++)
{
temp=a[i][0];
for(int j=0;j<m;j++)
{
a[i][j]=a[i][j]-a[0][j]*temp;
b[i][j]=b[i][j]-b[0][j]*temp;
}
}*/
//第一列ok了,接下来无非重复化列直到第m列化好,那这样又总共对那个二重循环操作了m次,所以说可以写个三重循环,恶心的是计算机不是我们
for(int p=0;p<m;p++)
{ //要保证每次对一列操作时该列元素中位于主对角线的那个元素为1,才对应我下面算法
if(a[p][p]!=0) temp=1/a[p][p]; //这里需要考虑除数不为0的情况
else { //否则怎么操作?可以将其持续与下一行交换直到不为0
for(int q=p+1;q<m;q++){
if(a[q][p]!=0){ //找到你了,交换吧
for(int e=0;e<m;e++)
{
temp2=a[p][e];
a[p][e]=a[q][e];
a[q][e]=temp2;
temp2=b[p][e]; //记得对b操作
b[p][e]=b[q][e];
b[q][e]=temp2;
}
temp=1/a[p][p];//这个操作仍需要,因为还得保证那个元素为1
break; //别忘了跳出循环
}
}
}
for(int j=0;j<m;j++)
{
a[p][j]*=temp;
b[p][j]*=temp;
}
for(int i=p+1;i<m;i++)
{
temp=a[i][p];
for(int j=0;j<m;j++)
{
a[i][j]=a[i][j]-a[p][j]*temp;
b[i][j]=b[i][j]-b[p][j]*temp;
}
}
}
printf("\n");
printf("the first step change a to:\n");
for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
{
printf("%f ",a[i][j]);
if(j==m-1) printf("\n");
}
}
//上述所有操作化成了上三角型矩阵,不放心可以打印一次a与b矩阵看一下,我这里出错了一次,但咱这步骤相当清晰,纠错容易
//接下来开始下半部分操作,化完整单位矩阵,需要再来个三重循环
for(int p=m-1;p>=0;p--)
{
temp=1/a[p][p]; //这里无需判断除数为0,为什么?因为上面的操作已经化为上三角矩阵,若a[p][p]还为0,则行列式必为0,不可逆
for(int j=0;j<m;j++)
{
a[p][j]*=temp;
b[p][j]*=temp;
}
for(int i=p-1;i>=0;i--)
{
temp=a[i][p];
for(int j=m-1;j>=0;j--)
{
a[i][j]=a[i][j]-a[p][j]*temp;
b[i][j]=b[i][j]-b[p][j]*temp;
}
}
}
//已经结束了,输出结果验证便好
printf("\n");
printf("the last step change a to:\n");
for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
{
printf("%f ",a[i][j]);
if(j==m-1) printf("\n");
}
}
printf("\n");
printf("the answer is:\n");
for(int i=0;i<m;i++)
{
for(int j=0;j<m;j++)
{
printf("%f ",b[i][j]);
if(j==m-1) printf("\n");
}
}
system("pause");
return 0;
}