高斯消元法是一个求解线性方程->n元一次方程组的解法,就是通过一些式子的加减来消掉一些未知数,来达到求解的过程,高斯消元法一般只考虑系数,也就是说数组中只存着各个未知数的系数,通过一些操作,使得最后的系数矩阵成为一个对角线的左下方全是0的矩阵
1 1 1 1 1 | 7
0 1 1 1 1 | 6
0 0 1 1 1 | 5
0 0 0 1 1 | 4
0 0 0 0 1 | 3
就像上面这样,当然1的位置可以是其他合法实数,这时我们发现,最后一个式子只剩下了最后一个未知数," | "后是等号后的常数项(x1+x2=3中的3),这时就可以直接求解最后一个未知数,然后通过一层一层的向回代入,便可以得到所有未知数的解,特别的若出现第i行第i列的值为0,则该方程组有不定解,所以我们可以通过将n个未知数组成一个等式看做是一个点在n维空间中的坐标,方程组有解时,一个点的坐标不可能通过另一个点的坐标来表示出,也就是所有的点互不相关,不能相互线性表出
代码
//By AcerMo
#include<cmath>
#include<cstdio>
#include<iostream>
using namespace std;
const double esp=1e-7;
int n;
double num[500][500];
bool gauss()
{
for (int i=1;i<=n;i++)//外层循环列数
{
int r=i;
for (int k=i+1;k<=n;k++)
if (fabs(num[k][i])>fabs(num[r][i])) r=k;//寻找当前列的最大
if (fabs(num[r][i])<esp) return 0;//该项为零无定解
if (r!=i) //当前行不是最大,则向下交换
for (int k=1;k<=n+1;k++)
swap(num[i][k],num[r][k]);
for (int k=i+1;k<=n;k++)
{
double mul=num[k][i]/num[i][i];
for (int j=i;j<=n+1;j++)
num[k][j]-=(num[i][j]*mul);//模拟相减
}
}
for (int i=n;i>0;i--)
{
for (int k=i+1;k<=n;k++)
num[i][n+1]-=(num[k][n+1]*num[i][k]);//回带
num[i][n+1]/=num[i][i];
}
return 1;
}
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
for (int k=1;k<=n+1;k++)
scanf("%lf",&num[i][k]);
if (!gauss()) puts("No Solution");
else
for (int i=1;i<=n;i++)
printf("%.2lf\n",num[i][n+1]);
return 0;
}