把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

luogu P3389 【模板】高斯消元法

题面传送门
高斯消元板子。
可以去翻翻七下数学书一元二次方程组中的代入消元法。
对于一般的整数方程我们可以用加减消元法。但是计算机不会,怎么办呢?
只能用算起来很复杂的代入消元法了。
一个一个系数来消。首先选择当前系数下最大的那个,这个可以保证精度。
然后将系数化为\(1\)
之后把剩下每个方程的当前未知数都消去。重复执行\(n\)次即可。
然后我们惊奇地发现,最后一个未知数解出来了。
这是我们就可以往回代入。
这时我们有发现,第\(i\)个方程就是关于\(x_{i}\)\(x_{n}\)地一个方程。这使我们往回代入计算变得很容易。
带入并计算即可。
code:

#include<cstdio>
#include<cmath>
using namespace std;
int n,m,k,x,y,z,now;
const double eps=1e-7;
double a[139][139],ans[139],pus;
inline void swap(double &x,double &y){x+=y,y=x-y;x-=y;}
int main(){
	freopen("1.in","r",stdin);
	register int i,j,k;
	scanf("%d",&n);
	for(i=1;i<=n;i++){
		for(j=1;j<=n+1;j++) scanf("%lf",&a[i][j]);
	}
	for(i=1;i<=n;i++){
		for(now=i,j=i+1;j<=n;j++) if(a[j][i]>a[now][i]) now=j;
		if(fabs(a[i][now])<eps){printf("No Solution\n");return 0;}
		if(now!=i)for(j=1;j<=n+1;j++) swap(a[i][j],a[now][j]); 
		pus=a[i][i];for(j=i;j<=n+1;j++) a[i][j]/=pus;
		for(j=i+1;j<=n;j++){
			for(pus=a[j][i],k=i;k<=n+1;k++) a[j][k]-=a[i][k]*pus;
		} 
	}
	ans[n]=a[n][n+1];
	for(i=n-1;i;i--){
		ans[i]=a[i][n+1];
		for(j=i+1;j<=n;j++) ans[i]-=a[i][j]*ans[j];
	}
	for(i=1;i<=n;i++) printf("%.2lf\n",ans[i]);
}
posted @ 2021-02-15 21:00  275307894a  阅读(55)  评论(0)    收藏  举报
浏览器标题切换
浏览器标题切换end