高斯消元是用来求解线性方程组的。
例如:给出以下方程组
2*x+y-z=8
-3*x-y+2*z=-11
-2+y+2*z=-3
由以上三个方程可以列出一个增广矩阵
2 1 -1 8
-3 -1 2 -11
-2 1 2 -3
通过化简增广矩阵可以得到
1 0 0 2
0 1 0 3
0 0 1 -1
由此可以知道三个未知量的解分别为
x=2;
y=3;
z=-1;
由以上分析可以写出以下代码用来求解线性方程组。
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#define N 110
using namespace std;
int equ,var;
int a[N][N];
int x[N];
int f_x[N];
int f_num;
int gcd(int a,int b)//求最大公约数
{
return b?gcd(b,a%b):a;
}
int lcm(int a,int b)//求最小公倍数
{
return a/gcd(a,b)*b;
}
int gauss()
{
int i,j,k;
int max_r;
int ta,tb;
int f_x_num;
int f_index;
int Lcm,tmp;
int col=0;
for(k=0;k<equ&&col<var;k++,col++)
{
max_r=k;
for(i=k+1;i<equ;i++)
if(abs(a[i][col])>abs(a[max_r][col]))
max_r=i;
if(max_r!=k)
for(j=k;j<var+1;j++)//将两行互换位置
swap(a[k][j],a[max_r][j]);
if(a[k][col]==0)
{
k--;
continue;
}
for(i=k+1;i<equ;i++)
{
if(a[i][col])
{
Lcm=lcm(abs(a[i][col]),abs(a[k][col]));
ta=Lcm/abs(a[i][col]);
tb=Lcm/abs(a[k][col]);
if(a[i][col]*a[k][col]<0)
tb=-tb;
for(j=col;j<var+1;j++)
a[i][j]=a[i][j]*ta-a[k][j]*tb;
}
}
}
//以上是化增广矩阵为行阶梯型矩阵
//以下是非递归回带过程
for(i=k;i<equ;i++)
if(a[i][col])
return -1;//证明无解
if(k<equ)
{
for(i=k-1;i>=0;i--)
{
f_num=0;
for(j=0;j<var;j++)
{
if(a[i][j]&&f_x[j])
{
f_x_num++;
f_index=j;
}
}
if(f_x_num>1)
continue;
tmp=a[i][var];
for(j=0;j<var;j++)
if(a[i][j]&&j!=f_index)
tmp-=a[i][j]*x[j];
x[f_index]=tmp;
f_x[f_index]=0;
}
return var-k;
}
for(i=var-1;i>=0;i--)
{
tmp=a[i][var];
for(j=i+1;j<var;j++)
{
if(a[i][j])
tmp-=a[i][j]*x[j];
}
if(tmp%a[i][i])
return -2;
x[i]=tmp/a[i][i];
}
return 0;
}
void import()
{
memset(a,0,sizeof(a));
memset(x,0,sizeof(x));
memset(f_x,1,sizeof(f_x));
for(int i=0;i<equ;i++)
for(int j=0;j<var+1;j++)
scanf("%d",&a[i][j]);
}
void Export()
{
if(f_num==-1)
printf("No Solution!\n");
else if(f_num==-2)
printf("With double but don`t has Integer solutions!\n");
else if(f_num>0)
{
printf("With many solutions,and the var number is: %d\n",f_num);
for(int i=0;i<var;i++)
{
if(f_x[i])
printf("x%d is not certain!\n",i+1);
else
printf("x%d: %d\n",i+1,x[i]);
}
}
else
{
for(int i=0;i<var;i++)
printf("x%d: %d\n",i+1,x[i]);
}
}
int main()
{
while(scanf("%d%d",&equ,&var)!=EOF)
{
import();
f_num=gauss();
Export();
}
return 0;
}
/*
2 2
1 1 2
1 -1 0
3 3
2 1 -1 8
-3 -1 2 -11
-2 1 2 -3
*/