题目链接:https://www.luogu.org/problem/P3389
题意:解方程数为n(<=100)的线性方程组的解。
思路:高斯消元法模板题,复杂度:O(n^3)。
AC代码:
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; const double eps=1e-8; const int maxn=105; int n; double a[maxn][maxn],ans[maxn]; void Gauss(){ for(int i=1;i<=n;++i){ int r=i; for(int j=i+1;j<=n;++j) //找主元系数绝对值最大的行 if(fabs(a[j][i])>fabs(a[r][i])) r=j; if(fabs(a[r][i])<eps){ //最大为0时无解 printf("No Solution "); return; } if(r!=i) swap(a[i],a[r]);//交换 double div=a[i][i]; for(int j=i;j<=n+1;++j) //系数化为1 a[i][j]/=div; for(int j=i+1;j<=n;++j){ //消元 div=a[j][i]; for(int k=i;k<=n+1;++k) a[j][k]-=div*a[i][k]; } } ans[n]=a[n][n+1]; for(int i=n-1;i>=1;--i){ //回带 ans[i]=a[i][n+1]; for(int j=i+1;j<=n;++j) ans[i]-=a[i][j]*ans[j]; } for(int i=1;i<=n;++i) printf("%.2f ",ans[i]); } int main(){ scanf("%d",&n); for(int i=1;i<=n;++i) for(int j=1;j<=n+1;++j) scanf("%lf",&a[i][j]); Gauss(); return 0; }
优化版本:
高斯-约旦消元法,相比与传统的高斯消元法,高斯-约旦消元法精度高、代码简单、没有回带过程。本质上与传统高斯消元法不同的是每选择一个主元,去消去其它方程的该变量时是将其它所有的方程都消去,而高斯消元法仅消去下面的方程,因此不需要回带。
AC代码:
#include<cstdio> #include<cmath> #include<algorithm> using namespace std; const double eps=1e-8; const int maxn=105; int n; double a[maxn][maxn]; void Gauss(){ for(int i=1;i<=n;++i){ int r=i; for(int j=i+1;j<=n;++j) //找主元系数的绝对值最大的一行 if(fabs(a[j][i])>fabs(a[r][i])) r=j; if(fabs(a[r][i])<eps){ //最大为0,无解 printf("No Solution "); return; } if(r!=i) for(int j=1;j<=n+1;++j) swap(a[i][j],a[r][j]); for(int j=1;j<=n;++j) //消元 if(j!=i){ double tmp=a[j][i]/a[i][i]; for(int k=i;k<=n+1;++k) a[j][k]-=a[i][k]*tmp; } } for(int i=1;i<=n;++i) printf("%.2f ",a[i][n+1]/a[i][i]); } int main(){ scanf("%d",&n); for(int i=1;i<=n;++i) for(int j=1;j<=n+1;++j) scanf("%lf",&a[i][j]); Gauss(); return 0; }