【Luogu】P3389高斯消元模板(矩阵高斯消元)

  题目链接

  高斯消元其实是个大模拟qwq

  所以就着代码食用

  首先我们读入

for(int i=1;i<=n;++i)
        for(int j=1;j<=n+1;++j)    scanf("%lf",&s[i][j]);

  读入肯定没什么问题(不过我在这卡了一分多钟)

  然后我们要进行消元操作

  所谓消元操作其实就是对于输入的矩阵

  比如说

  9 3 2 2

  1 4 7 3

  1 3 4 5

  进行一番乱搞,使得第当前枚举的(比如说枚举第i行第i列)s[i][j]系数变成1。

  实际上就是整行同除qwq

  比如我们除完第一行第一列的之后,矩阵就变成这样

  1  0.33 0.22 0.22

  1 4 7 3

  1 3 4 5

  这样,然后把其他行的这个元消掉

  1 0.33 0.22 0.22

  0 3.67 6.78 2.78

  0 2.67 3.78 3.78

  这样子。

  然后接着去消下一行的元。

  最后我们可以得到一个阵列

  1.00 0.33 0.22 0.22
  0.00 1.00 1.85 0.76
  0.00 0.00 1.00 -2.39

  观察到最后一行表示的方程式,xn=-2.39

  然后可以解出上一行的xn-1

  然后一直往回带就好了

  

#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cctype>
#include<cstring>
#include<cmath>
#define Exit {printf("No Solution"); return 0;    }
using namespace std;

inline long long read(){
    long long num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')    f=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        num=num*10+ch-'0';
        ch=getchar();
    }
    return num*f;
}

double s[200][200];
double ans[2000];

int main(){
    int n=read();
    for(int i=1;i<=n;++i)
        for(int j=1;j<=n+1;++j)    scanf("%lf",&s[i][j]);
    for(int i=1;i<=n;++i){
        int now=i;
        if(!s[i][i])    Exit;
        for(int j=now;j<=n;++j)
            if(fabs(s[j][i])>fabs(s[now][i]))    now=j;
        if(now!=i)    swap(s[i],s[now]);
        double div=s[i][i];
        for(int j=i;j<=n+1;++j)    s[i][j]/=div;
        for(int j=i+1;j<=n;++j){
            double ret=s[j][i];
            for(int k=i;k<=n+1;++k){
                s[j][k]-=ret*s[i][k];
            }
        }
    }
    ans[n]=s[n][n+1];
    for(int i=n-1;i;--i){
        double now=0;
        for(int j=i+1;j<=n;++j)    now+=ans[j]*s[i][j];
        ans[i]=s[i][n+1]-now;
    }
    for(int i=1;i<=n;++i)    printf("%.2lf
",ans[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/cellular-automaton/p/8227324.html