高斯消元法

高斯消元

这里只是概述,更详细的内容看一本通金牌导航吧,蒟蒻能力有限qwq

高斯消元,用于求解n元一次方程组
这里介绍高斯约旦消元法(反正我看的题解是这么叫的)
该方法的思路是:通过一系列消元操作,使得每一变量仅出现在一个方程中
简要流程如下:
(1)对于每一个n元一次方程,将形如∑a[i]x[i]=b的方程转化成行列式形式
(2)枚举每一行,假设我们枚举到第i行,我们希望x[i]最终仅在第i个方程中出现,称x[i]为该行的主元。如果第i行的主元系数不是第i~n个方程中最大的,则找到那个系数最大的方程,将行列式中对应的两行互换,使得第i行的主元系数最大化,以减小精度误差
(3)设主元系数为K,将第i行每一项系数除以K,目的是将主元系数变为1
(4)枚举除第I行以外的每一行,令该行x[i]的系数为K,将该行与第i行放大K倍得到的式子相减,消去该行的x[i]项
(5)重复上述步骤,直至n元一次不等式组化为n个一元一次方程,然后直接求解就行了

看了代码就会更明白一些
洛谷P4035 [JSOI2008]球形空间产生器

#include<bits/stdc++.h>
using namespace std;
#define il inline
#define re register
il int read(){
	int s=0,w=1;char c=getchar();
	while(c<'0'||c>'9'){ if(c=='-') w=-1;c=getchar();}
	while(c>='0'&&c<='9'){ s=(s<<1)+(s<<3)+c-'0';c=getchar();}
	return s*w;
}
const int N=20;
const double eps=1e-8;
int n,m;//m=n+1
double f[N][N];
il void Gauss(){
	for(re int i=1;i<=n;i++){
		int l=i;double K=0;
		for(re int j=i+1;j<=n;j++)
			if(fabs(f[j][i])-fabs(f[l][i])>eps) l=j;
		if(l!=i) for(re int j=i;j<=m;j++) swap(f[i][j],f[l][j]);
		K=f[i][i];
		for(re int j=i;j<=m;j++) f[i][j]/=K;
		for(re int j=1;j<=n;j++){
			if(j==i) continue;
			K=f[j][i];
			for(re int k=i;k<=m;k++) f[j][k]-=f[i][k]*K;
		}
	}
}
int main()
{
	n=read(),m=n+1;
	for(re int i=0;i<=n;i++){
		for(re int j=1;j<=n;j++) scanf("%lf",&f[i][j]);
	}
	for(re int i=1;i<=n;i++){
		double D=0;
		for(re int j=1;j<=n;j++){
			D+=f[i][j]*f[i][j]-f[0][j]*f[0][j];
			f[i][j]=2*(f[i][j]-f[0][j]);
		}
		f[i][m]=D;
	}
	Gauss();
	for(re int i=1;i<n;i++) printf("%.3lf ",f[i][m]/f[i][i]);
	printf("%.3lf",f[n][m]/f[n][n]);
	
}

end

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值