洛谷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<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; 
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值