( 数论专题 )【 高斯消元 】
作用:解一元多次方程。 例如:x+y=2, 2x+3y=5 . 解得x=1,y=1
这里介绍的是高斯-约旦消元法。
相对于传统的高斯消元,约旦消元法的精度更好、代码更简单,没有回带的过程。
约旦消元法大致思路如下:
1.选择一个尚未被选过的未知数作为主元,选择一个包含这个主元的方程。
2.将这个方程主元的系数化为1。
3.通过加减消元,消掉其它方程中的这个未知数。
4.重复以上步骤,直到把所有式子变成形如: a1+b0+c*0……=d
我们用矩阵表示每一项系数以及结果
模板
#include<bits/stdc++.h>
using namespace std;
const int maxn = 105;
double a[maxn][maxn];
int n;
int main()
{
/*
抄板子的时候仔细分辨 i 和 j
输入样式:
3
1 3 4 5 x+3y+4z=5
1 4 7 3 对应的-> x+4y+7z=3 答案-> -0.97 5.18 -2.39
9 3 2 2 9x+3y+2z=2
*/
cin>>n; // n个未知数,n+1个式子的一元多次方程。
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 mx = i;
for ( int j=i+1; j<=n; j++ ) { // 选出该列最大的系数
if ( fabs(a[j][i]) > fabs(a[mx][i]) ) mx=j;
}
for ( int j=1; j<=n+1; j++ ) { // 交换
swap( a[i][j], a[mx][j] );
}
if ( fabs(a[i][i])<0.0000001 ) { // 最大值等于0,说明该列都是0,肯定无解
printf("No Solution\n");
return 0;
}
for ( int j=1; j<=n; j++ ) { // 每一项都减去一个数(就是小学加减消元)
if ( j!=i ) {
double tmp = a[j][i]/a[i][i];
for ( int k=i+1; k<=n+1; k++ ) {
a[j][k] -= a[i][k]*tmp;
}
}
}
}
//上述操作结束后,矩阵会变成这样
/*
k1*a=e1
k2*b=e2
k3*c=e3
k4*d=e4
*/
//所以输出的结果要记得除以该项系数,消去常数
for( int i=1; i<=n; i++ ) {
printf("%.2lf\n",a[i][n+1]/a[i][i]);
}
return 0;
}