高斯消元
$a_1x+b_1y+c_1z=d_1$
$a_2x+b_2y+c_2z=d_2$
$a_3x+b_3y+c_3z=d_3$
高斯消元思路
约旦消元法大致思路如下:
1.选择一个尚未被选过的未知数作为主元,选择一个包含这个主元的方程。
2.将这个方程主元的系数化为 $1$。
3.通过加减消元,消掉其它方程中的这个未知数。
4.重复以上步骤,直到把每一行都变成只有一项有系数。
高斯消元做法
先消一个元 例如 $x$
$1$ 式 $\times a_2$ — $2$ 式 $\times a_1$
$1$ 式 $\times a_3$ — $3$ 式 $\times a_1$
消去了$x$,并且成为二元二次方程再将 $2$ 式和 $3$ 式的 $y$ 消去,可以求出 $z$。将 $z$ 回代 $2$ 式,求出 $y$。将 $z$,$y$ 回带 $1$ 式,求出 $x$。
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<map>
#include<cmath>
using namespace std;
int r_r(){//快读
int x=0,f=1;
char c=getchar();
while(!isdigit(c)){
if(c=='-')f=-1;
c=getchar();
}
while(isdigit(c)){
x=(x<<1)+(x<<3)+(c^48);
c=getchar();
}
return x*f;
}
int n;
double a_a[101][101];
int main(){
n=r_r();
for(int i=0;i<n;i++)
for(int j=0;j<=n;j++)scanf("%lf",&a_a[i][j]);//读入
for(int i=0;i<n;i++){
int m_a=i;//初值,线性,到这个编号
for(int j=i+1;j<n;j++)//找这一列(这个元绝对值最小的系数)中最小的值
if(fabs(a_a[j][i])<fabs(a_a[m_a][i]))m_a=j;
for(int j=0;j<=n;j++)swap(a_a[i][j],a_a[m_a][j]);//交换这两列
if(!a_a[i][i]){//若最小值是 0 无解
cout<<"No Solution"<<endl;
return 0;
}
for(int j=0;j<n;j++){
if(i==j)continue;
double l_l=a_a[j][i]/a_a[i][i];//每个方程的这一列(这个元)的倍数
for(int k=i+1;k<=n;k++)//消去这个元
a_a[j][k]-=a_a[i][k]*l_l;
}
}
for(int i=0;i<n;i++)//方程中只有对角线还有数,每个数只出现了一次。
//可以看成 n 个一元一次方程
printf("%.2lf\n",a_a[i][n]/a_a[i][i]);//求解输出
return 0;
}