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

求解一个线性方程组

思路:高斯消元

流程:

  1. 枚举每一列 ii
  2. 找该列最大值所在的行,将该行和 ii 行进行交换
  3. 消元,参考代码
#include<iostream>
#include<cstdio>
#include<cmath>
#define MAXN 110
using namespace std;
int n;double a[MAXN][MAXN];
int main(){
#ifdef WINE
    freopen("data.in","r",stdin);
#endif
    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++){ // 枚举每一列
        int m=i;
        for(int j=i+1;j<=n;j++) // 找出 i 列绝对值最大的元素下标,从 i+1 行开始向下找
            if(fabs(a[j][i])>fabs(a[m][i]))m=j;
        for(int j=1;j<=n+1;j++)swap(a[i][j],a[m][j]); // 将这一行交换上去
        if(!a[i][i]){printf("No Solution\n");return 0;} // 最大值为 0 ,无解!
        // 对每一行进行操作,使得当前列除了最大值的那一行,其他的归零
        for(int j=1;j<=n;j++){ // 遍历每一行
            if(j==i)continue; // 跳过最大值所在的行
            double tmp=a[j][i]/a[i][i]; // 消元所需的系数
            for(int k=i+1;k<=n+1;k++) // 前面列都已经消过元了
                a[j][k]-=a[i][k]*tmp; // a[j][i] 消后是 0,后面没有用到,所以就略掉了
        }
    }
    // 此时系数矩阵是一个对角矩阵,只有对角线上的元素是有效的
    for(int i=1;i<=n;i++)
        printf("%.2lf\n",a[i][n+1]/a[i][i]);
    return 0;
}

posted @ 2020-06-27 20:28  winechord  阅读(94)  评论(0编辑  收藏  举报