和求解行列式的值類似,當某一列的常數(shù)項全為0時,方程組無解或有無窮多解,此時退出程序;否則將列主元下面的元素逐個消去,直至循環(huán)結(jié)束。要注意的是為了保持數(shù)值的穩(wěn)定性(精度),每次選取的列主元的系數(shù)都是該列絕對值最大的那個。
#include <cstdio>
#include <cmath>

#define MAXN 100
#define eps 1e-9


int gauss_elimination(int n,double a[][MAXN],double b[])
{
int i,j,k,row;
double maxp,t;

for(k=0;k<n;k++)
{//行標+列標
for(maxp=0,i=k;i<n;i++)//行標
if (fabs(a[i][k])>fabs(maxp))//選取絕對值最大的主元素,保持數(shù)值穩(wěn)定性
maxp=a[row=i][k];
if(fabs(maxp)<eps) return 0;

if(row!=k)
{
for(j=k;j<n;j++)
t=a[k][j],a[k][j]=a[row][j],a[row][j]=t;
t=b[k],b[k]=b[row],b[row]=t;
}
for(j=k+1;j<n;j++)//列標
for(a[k][j]/=maxp,i=k+1;i<n;i++)//行標
a[i][j]-=a[i][k]*a[k][j];
for(b[k]/=maxp,i=k+1;i<n;i++)//行標
b[i]-=b[k]*a[i][k];
}
for(i=n-1;i>=0;i--)
for(j=i+1;j<n;j++)
b[i]-=a[i][j]*b[j];
return 1;
}

int main()
{
int i,j,n;
double a[MAXN][MAXN],b[MAXN];

while(scanf("%d",&n),n)
{

for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
scanf("%lf",&a[i][j]);
scanf("%lf",&b[i]);
}
if(gauss_elimination(n,a,b))
for(i=0;i<n;i++)
printf("x%d : %.2lf\n",i+1,b[i]);
else
puts("Uncertain");
}
return 0;
}