版权声明:转载请声明出处,谢谢配合。 https://blog.csdn.net/zxyoi_dreamer/article/details/82766272
参考题目:洛谷P3389
#解析:
首先高斯消元是干什么的?
求解如下形式的线性方程组
那么现在我们考虑把原来的方程转化成如下的
矩阵
考虑将前面的矩阵(前 的部分)消成每行每列只有一个元素不为0,那么不为零的那个列所对应的未知数就是方程的解。
第一份代码是回代版的高斯消元。
考虑将矩阵消元成一个上三角矩阵,就是只有上三角的元素非0,那么最后一行可以直接得出最后一个元素的解,然后再利用这个解将这一列所有的该元素系数全部消成0。
第二份代码是不用回代的高斯消元。
就是直接利用这一行的非0元将该列所有系数全部消为0,
记录该行保留的是第几个数。
对于方程无解的情况(仔细想一想,不存在的),或者有无穷多解的情况。
当某一列在消元过程中全部为0时,即在该列没有任何系数,那么这个元素可以取任意值,即方程有无数组解,直接退出,防止除以0引发错误。
代码1:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
inline
ll getint(){
re ll num=0;
re char c;
re bool f=1;
while(!isdigit(c=gc()))if(c=='-')f=0;
while(isdigit(c))num=(num<<1)+(num<<3)+(c^48),c=gc();
return f?num:-num;
}
double a[102][102];
int n;
inline
bool gauss(){
for(int re i=1;i<=n;++i){
int pos=i;
for(int re j=i;j<=n;++j){
if(fabs(a[j][i])-fabs(a[pos][i])>=1e-6)pos=j;
}
if(i!=pos)swap(a[i],a[pos]);
if(fabs(a[i][i])<1e-6)return false;
for(int re j=i+1;j<=n+1;++j)a[i][j]/=a[i][i];
a[i][i]=1;
for(int re j=i+1;j<=n;++j){
double tmp=a[j][i];
for(int re k=i;k<=n+1;++k)
a[j][k]-=a[i][k]*tmp;
}
}
return true;
}
signed main(){
n=getint();
for(int re i=1;i<=n;++i)
for(int re j=1;j<=n+1;++j)
a[i][j]=getint();
if(!gauss()){
puts("No Solution");
}
else{
for(int re i=n-1;i;--i){
for(int re j=i+1;j<=n;++j)
a[i][n+1]-=a[i][j]*a[j][n+1],a[i][j]=0;
}
for(int re i=1;i<=n;++i){
printf("%.2f\n",a[i][n+1]);
}
}
return 0;
}
代码2:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
inline
ll getint(){
re ll num=0;
re char c;
re bool f=1;
while(!isdigit(c=gc()))if(c=='-')f=0;
while(isdigit(c))num=(num<<1)+(num<<3)+(c^48),c=gc();
return f?num:-num;
}
double a[102][102];
int w[101];
double x[101];
int n;
inline
bool gauss(){
for(int re i=1;i<=n;++i){
int pos=-1;
double maxn=0.0;
for(int re j=1;j<=n;++j){
if(fabs(a[i][j])-1e-6>maxn)
maxn=fabs(a[i][j]),pos=j;
}
if(pos==-1)return false;
w[i]=pos;
for(int re j=1;j<=n;++j){
if(i!=j){
double tmp=a[j][pos]/a[i][pos];
for(int re k=1;k<=n+1;++k)a[j][k]-=a[i][k]*tmp;
}
}
}
return true;
}
int main(){
n=getint();
for(int re i=1;i<=n;++i)
for(int re j=1;j<=n+1;++j)
a[i][j]=getint();
if(!gauss()){
puts("No Solution");
}
else {
for(int re i=1;i<=n;++i)x[w[i]]=a[i][n+1]/a[i][w[i]];
for(int re i=1;i<=n;++i)printf("%.2f\n",x[i]);
}
return 0;
}