洛谷P3389高斯消元法

高斯消元法是一个求解线性方程->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
#include
#include
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])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; 
}

你可能感兴趣的:(高斯消元)