@Junlier
2018-08-28T20:24:28.000000Z
字数 1834
阅读 1880
数学方法——高斯消元
高斯消元
致敬yyb
以洛古的模板题为准……戳我
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<ctime>
#include<queue>
#include<stack>
#include<vector>
#define rg register
#define il inline
#define lst long long
#define ldb long double
#define N 150
using namespace std;
const int Inf=1e9;
int n;
ldb g[N][N];
il int read()
{
rg int s=0,m=0;rg char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')m=1;ch=getchar();}
while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
return m?-s:s;
}
int main()
{
n=read();
for(rg int i=1;i<=n;++i)
for(rg int j=1;j<=n+1;++j)
scanf("%Lf",&g[i][j]);
//i是枚举的每一个方程 1~n
//j是方程的每一项 1~n+1
for(rg int k=1;k<=n;++k)//要消元的未知数(也同时是第几个方程)
{
rg int now=k;//每一个方程要把一个未知数消元
for(rg int i=k+1;i<=n;++i)//找当前要处理的未知数的系数的最大值
if(fabs(g[now][k])<fabs(g[i][k]))now=i;
for(rg int j=k;j<=n+1;++j)//换到这一行来
swap(g[now][j],g[k][j]);
if(!g[k][k])//还没开始消元就没东西了,肯定无解
{
puts("No Solution");return 0;
}
for(rg int j=k+1;j<=n+1;++j)//系数化为1
g[k][j]/=g[k][k];
g[k][k]=1;
for(rg int i=k+1;i<=n;++i)//其他每一个方程把这个元消掉(每一个方程的这个元置为0)
{
for(rg int j=k+1;j<=n+1;++j)
g[i][j]-=g[i][k]*g[k][j];//一定要纸上画图模拟消元过程!
g[i][k]=0;
}
}//每次做一个未知数的消元,最后剩下一个三角阵 yeh
//每个方程回代求解
for(rg int k=n;k>=1;--k)
{
for(rg int i=k+1;i<=n;++i)
{
g[k][n+1]-=g[k][i]*g[i][n+1];//没一个方程的n+1位置是对应未知数的答案(逐个往上消掉了)
g[k][i]=0;//置为0,这一项已经经过回代变成常数并被减掉了 yeh
}
g[k][n+1]/=g[k][k];//除掉自己方程的系数(其实系数已经在上面被化为1了……)
g[k][k]=1;
}//每回代一个方程就解出一个未知数,最后留下的矩阵就是每个未知数的解了 yeh
for(rg int i=1;i<=n;++i)
printf("%.2Lf\n",g[i][n+1]);
return 0;
}