高斯消元
理论
求解线性方程组,例如
\[\begin{cases} a_{1,1}x_1+a_{1,2}x_2+a_{1,3}x_3=b_1\\ a_{2,1}x_1+a_{2,2}x_2+a_{2,3}x_3=b_2\\ a_{3,1}x_1+a_{3,2}x_2+a_{3,3}x_3=b_3 \end{cases} \]将它转化为矩阵乘法
\[\left[ \begin{matrix} a_{1,1}&a_{1,2}&a_{1,3}\\ a_{1,1}&a_{1,2}&a_{1,3}\\ a_{1,1}&a_{1,2}&a_{1,3} \end{matrix} \right] \times \left[ \begin{matrix} x_1\\ x_2\\ x_3 \end{matrix} \right] = \left[ \begin{matrix} b_1\\ b_2\\ b_3 \end{matrix} \right] \]上面的三个矩阵还是太麻烦了,我们将他变为增广矩阵
\[\left[ \begin{matrix} a_{1,1}&a_{1,2}&a_{1,3}&b_1\\ a_{1,1}&a_{1,2}&a_{1,3}&b_2\\ a_{1,1}&a_{1,2}&a_{1,3}&b_3 \end{matrix} \right] \]然后我们定义初等行变换
1.交换两行
2.将同一行的元素同时乘 \(val\)
3.将第 \(i\) 行的元素加到第 \(j\) 行上面
不难发现初等行变换不会改变方程的解。然后就像我们常规解方程一样进行消元就可以了。
具体操作为,对于每一个未知数,我们取一个最大的 \(a\) ,然后用初等行变换将其他行对应的地方变成 \(0\) ,最后我们可以得到一个这样的矩阵
\[\left[ \begin{matrix} a'_1&0&0&b'_1\\ 0&a'_2&0&b'_2\\ 0&0&a'_3&b'_3 \end{matrix} \right] \]我们就可以很方便的进行求解了。
例题:洛谷P3389
#include
#define db double
using namespace std;
db a[105][105];
int n;
int main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n+1;j++)
cin>>a[i][j];
for(int i=1;i<=n;i++){
int maxhang=i;
for(int j=i+1;j<=n;j++)
if(abs(a[j][i])>=abs(a[maxhang][i]))
maxhang=j;
for(int j=1;j<=n+1;j++)
swap(a[maxhang][j],a[i][j]);
if(a[i][i]==0) {
cout<<"No Solution\n";
return 0;
}
for(int j=1;j<=n;j++){
if(j==i) continue;
db sb=a[j][i]*1.0/a[i][i];
for(int k=i;k<=n+1;k++)
a[j][k]-=a[i][k]*sb;
}
}
for(int i=1;i<=n;i++) {
cout<