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]);
}

浙公网安备 33010602011771号