洛谷——P3389 【模板】高斯消元法 高斯消元总结

P3389 【模板】高斯消元法

以下内容都可省略,直接转大佬博客%%%

高斯消元总结

只会背板子的蒟蒻,高斯消元是什么,不知道诶,看到大佬们都会了这个水题,蒟蒻只好也来切一切

高斯消元最大用途就是解多元一次方程组——引自某大佬原话

的确是这样的,那么如何去做呢?

类比二元一次方程组:

$a_1x+b_1y=c_1$

$a_2x+b_2y=c_2$

emmm,怎么做呢?消去一项!嗯。

也就是把第$i$个方程的第$i$项变成1

$\frac{a_1}{a_1}x+\frac{b_1}{a_1}y=\frac{c_1}{a_1}$

也就是$x+\frac{b_1}{a_1}y=\frac{c_1}{a_1}$

再用这个式子消去第$i+1$到$n$方程的第$i$项,

$\frac{a_2}{a_2}x+\frac{b_2}{a_2}y=\frac{c_2}{a_2}$

也就是$x+\frac{b_2}{a_2}y=\frac{c_2}{a_2}$

用这一项减去上一项$0+(\frac{b_2}{a_2}-\frac{b_1}{a_1})y=\frac{c_2}{a_2}-\frac{c_1}{a_1}$

由于将每一项的系数都化为一比较麻烦,我们尝试直接消去那一项

$a_1x+b_1y=c_1$

$a_2x+b_2y=c_2$

第二项变成$a_2\times \frac{a_1}{a_2}x+b_2\times \frac{a_1}{a_2}y=c_2\times \frac{a_1}{a_2}$

消去第一项$(a_2\times \frac{a_1}{a_2}-a_1)x+(b_2\times \frac{a_1}{a_2}-b_1)y=c_2\times \frac{a_1}{a_2}-c_1$

这样是可行的,同样是把第二个方程组的第一项系数化为$0$

for(int i=1;i<=n;i++){
        if(!a[i][i]) return puts("No Solution\n"),0;
        for(int j=i+1;j<=n;j++)
            for(int k=n+1;k>=i;k--)
                a[j][k]=a[j][k]*a[i][i]/a[j][i]-a[i][k];
}
//消元

不过大佬们都是这样写的,见代码:

$a_1x+b_1y=c_1$

$(a_2-\frac{a_2}{a_1}\times a_1)x+(b_2-\frac{a_2}{a_1}\times b_1)y=c_2-\frac{a_2}{a_1}\times c_1$

貌似这才是正确的操作,相当于把第一个方程同除以$a_1$,第二个方程减去$a_2\times...$

回代过程略。。。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>

using namespace std;

double a[205][205],x[205];
int n;

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n+1;j++)
            scanf("%lf",&a[i][j]);
    
    for(int i=1;i<=n;i++){
        if(!a[i][i]) return puts("No Solution\n"),0;
        for(int j=i+1;j<=n;j++)
            for(int k=n+1;k>=i;k--)
                a[j][k]-=a[i][k]*a[j][i]/a[i][i];
    }//消元 
    
    for(int i=n;i;i--){
        x[i]=a[i][n+1];
        for(int j=n;j>i;j--) x[i]-=a[i][j]*x[j];
        x[i]/=a[i][i];
    }//回代 
    for(int i=1;i<=n;i++)
        printf("%.2lf\n",x[i]);
    
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/song-/p/9776102.html