想不到大名鼎鼎的高斯消元就只是个
O(n3)
的玩意儿……
算法流程还是先走一下:
1、先将每一条方程的各个系数都统计进矩形,并且将方程等式右边的常数放进矩形的最后一列,以便之后进行统一的计算。
2、我们要做的就是对于每一个未知数(x、y……),只留下一条式子中含有它的系数,并且这个系数为“1”。
3、对于每一个未知数x,我们每次寻找x中系数k最大的,只留下它,然后将这条方程整体除掉k,那么未知数x的系数就变成了1。接下来像我们在纸上解方程一样消掉其他式子中的x的系数,(至于为什么每次都要找一个系数最大的,并不是什么玄学,只是因为这样可以防止爆精度,自己可以推一下)
4、至于那些乘乘除除的还是需要自己在纸上推一下,这种东西真的不太好记。
void work(int n){
for(int i=0;i<n;i++)A[i][n]=B[i];
for(int i=0;i<n;i++){
int p=i;
for(int j=i+1;j<n;j++){
if(fabs(A[j][i])>fabs(A[p][i]))p=j;
}
if(p!=i)for(int j=0;j<=n;j++)swap(A[i][j],A[p][j]);
for(int j=i+1;j<=n;j++)A[i][j]/=A[i][i];
// A[i][i]=1;
for(int j=0;j<n;j++){
if(j==i)continue;
for(int k=i+1;k<=n;k++)A[j][k]-=A[j][i]*A[i][k];
// A[j][i]=0;
}
}
for(int i=0;i<n;i++)ans[i]=A[i][n];
}
在代码中我标记掉了两句话,因为不管有没有这两句话,程序都是对的,但是加了这两句话,你就能明白流程2中到底这样用这段代码来实现。