高斯消元学习笔记
高斯消元,是一种求解线性方程组的办法(虽然我感觉好麻烦,但毕竟电脑的思维不能跟我们相提并论)
首先,我们可以把
例如:
初等行列变换:(就是高斯消元的几种方式)
-
用一个非零整数乘以某一行
-
将其中的一行整数加到其他行上
-
交换两行的位置
算法步骤:
-
枚举每一列
i ,也就是第i 个未知数 -
运用初等行列变换
1 ,将第i 行第i 位变成1 -
运用初等行列变换
2 ,将其他行第i 位变成0
举例:
最后就求解完毕了
注意事项:
-
若出现
\begin{bmatrix} ... & ... & ... & ...\\ 0 & ... & 0 & k(k \in \mathbb N_+)\\ ... & ... & ... & ...\end{bmatrix} 的情况,则显然方程组无解 -
若出现
k 个\begin{bmatrix} 0 & ... & 0 & 0\end{bmatrix} 的情况,则方程组有无数个解(前提不满足1 ),且主元有n-k 个,自由元有k 个
代码实现中会遇到一些问题,需要酌情调整,Gauss消元部分代码如下
void gauss()
{
for(int i=1;i<=n;i++)
{
int maax=i;
for(int j=i+1;j<=n;j++)
if(fabs(t[j].a[i])>fabs(t[maax].a[i])) maax=j; //fabs为浮点数绝对值,找出当前主元最大的系数
swap(t[i],t[maax]);
if(!t[i].a[i]) //最大系数为0,显然无解或无唯一解
{
printf("No Solution\n");
exit(0);
}
double tur=t[i].a[i];
for(int j=1;j<=n+1;j++) t[i].a[j]/=tur;//第二步
for(int j=1;j<=n;j++)
{
if(j==i) continue;
tur=t[j].a[i];
for(int k=1;k<=n+1;k++) t[j].a[k]-=tur*t[i].a[k];//第三步
}
}
}
模板题:【模板】高斯消元法
例题:
[SDOI2006]线性方程组
[JSOI2008]球形空间产生器
当然上述讲的高斯消元只是单纯的解线性方程,高斯消元还有很多变式。一般来说,高斯消元不会单独出题,常常会和其他知识点一起捆绑出题
异或高斯消元: [JSOI2012]始祖鸟 (题解)