题目链接
何为高斯消元
说一句实在的,平时解方程就是一种高斯消元的过程。也许你会觉得没啥神奇的,但我们平时解方程可以说解法很多,路径可能不一样。而高斯消元呢运用编程的语言,其实是一种固定的解法。
高斯消元略不同于平时解方程,他将方程转化成矩阵,因而,进行简简单单的加减乘除即可。
例如原方程为
不得不说,运算得好复杂啊。当然我们解方程可能计算量会小一些。
算法流程
我们消元是一步一步消的,因此,最后的矩阵不为0的应是斜着下来,如上图。
1.在消第i个元时,我们需要找主元,要找i这一系数不为0的。
2.暴力消掉其他行的这一个元
3.求答案,将第i行仅存的第i个元的解求出来。
代码难度并不很大,作为一个模板,还是需要掌握。
//n个方程,n个元
for (int i = 1;i <= n; i ++){//枚举消去的第i个元
int t;
for (t = i ;!a[t][i] && t <= n; t ++);//确定主方程,这一个方程的第i个元系数不能为0.
for (int j = 1;j <= n + 1;j ++)//这里把它放到合适位置,我们所构造的最后矩形是斜着下来的。
swap(a[i][j],a[t][j]);
for (int j = 1;j <= n ;j ++){
if (j == i || a[i][i] == 0)
continue;
double q = a[j][i] / a[i][i];//消去这一个元
for (int k = 1;k <= n + 1;k ++)//方程都减去这一个数。
a[j][k] -= q * a[i][k];
}
}
值得注意的是,有一些题目有精度问题,因而就会出错,本题这样写没有问题,但放在GUIDE的编译器上使用就会有精度问题,CB就没问题。机房的GUIDE我用的MinGW-5.1.4。
因此呢,最好还是处理一下精度。
特殊处理
当然,这样一道题目,是肯定有解的,如果方程组数与未知数组数不等,我们就要判断有无解,那么就只是方程是否有自由元了,也就是说方程是否有多个解。一般来说,算法结束后,有一行全是0,那么被消去的未知数可以任意取值,也就是自由元。
//判断是否有多解
bool wrong(){
for (int i = 1;i <= n;i ++){
if (a[i][i] != 1)
return 0;
int f = 0;
for (int j = 1;j <= n; j ++){
if (i != j && a[i][j] != 0)
f ++;
}
if (f)
return 1;
}
return 0;
}
当然这些处理都是基本操作,一般来说没有这么简单,也没有这么轻松让人看出来可以用高斯消元,因为高斯消元的时间复杂度很大,是N三方的,近乎暴力。。。所以说高斯消元一般来说适用的数据基本小于1000.
在这里给一个高端操作的链接