版权声明:欢迎大家转载,转载请标明出处。 https://blog.csdn.net/ylsoi/article/details/82933289
题目大意:
求解线性方程组。
判断惟一解,无穷解,无解的三种情况。
高斯消元:
洛谷的模板题好像怎么打都可以过,也没有具体区分无穷解和无解的情况,看来这个题才是高斯消元的真正模板。
惟一解:
这个大概是最好判断的了,在每次消元的时候都没有出现系数全部都为0的情况即整个线性方程组有惟一解。
无穷解和无解:
两种情况的判断稍微有一些麻烦,但是可以这样理解:如果一个线性方程在高消的过程中出现了某一列的系数全部为0,也就是出现了自由元,那么可以肯定一定不会存在惟一解。
那么剩下来的元和方程则构成了一组 {未知数<方程数} 的方程组,如果这个方程是有无穷解的,那么自由元任意取值的情况下,接下来的未知数都可以使这个方程数大于未知数的方程组恰好成立,同时其中必定有些方程之间线性相关,那么将最后一项系数消完之后,剩下来的系数为0的方程必定全部都是这种情况:
那么反过来,当存在自由元之后, {未知数<方程数} ,如果接来的方程不能恰好使得剩下来的未知数成立 ,那么将会是这种情况:
于是我们只需要在存在了自由元之后,跳过这列未知数,然后接下来的未知数继续从这个方程开始消元,判断一下最后系数为0的方程的情况即可。
//本文纯属自己的拙见,如有错误,欢迎指正。
#include<bits/stdc++.h>
#define REP(i,a,b) for(int i=a,i##_end_=b;i<=i##_end_;++i)
#define DREP(i,a,b) for(int i=a,i##_end_=b;i>=i##_end_;--i)
typedef long long ll;
using namespace std;
void File(){
freopen("luogu2455.in","r",stdin);
freopen("luogu2455.out","w",stdout);
}
template<typename T>void read(T &_){
int __=0,mul=1; char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')mul=-1;
ch=getchar();
}
while(isdigit(ch))__=(__<<1)+(__<<3)+(ch^'0'),ch=getchar();
_=__*mul;
}
const int maxn=100+10;
const double eps=1e-6;
int n,flag=1;
double a[maxn][maxn],ans[maxn];
void print(int id){
printf("Matrix #%d\n",id);
REP(i,1,(n+1)*5)putchar('-');
putchar('\n');
REP(i,1,n){
REP(j,1,n+1)printf("%.2lf ",a[i][j]);
putchar('\n');
}
REP(i,1,(n+1)*5)putchar('-');
putchar('\n');
putchar('\n');
}
void Gauss(){
int p=1;
REP(i,1,n){
DREP(j,n,p+1)if(fabs(a[j][i])>fabs(a[j-1][i]))swap(a[j],a[j-1]);
if(fabs(a[p][i])<eps)continue;
REP(j,i+1,n+1)a[p][j]/=a[p][i]; a[p][i]=1;
REP(j,p+1,n){
REP(k,i+1,n+1)a[j][k]-=a[p][k]*a[j][i];
a[j][i]=0;
}
++p;
//print(i);
}
if(p==n+1){
DREP(i,n,1){
ans[i]=a[i][n+1];
REP(j,1,n-1)a[j][n+1]-=a[j][i]*ans[i];
}
}
else{
flag=0;
REP(i,p,n)if(fabs(a[i][n+1])>eps)flag=-1;
}
}
int main(){
// File();
read(n);
REP(i,1,n)REP(j,1,n+1)read(a[i][j]);
Gauss();
if(flag==1)REP(i,1,n)printf("x%d=%.2lf\n",i,ans[i]);
else printf("%d\n",flag);
return 0;
}