高斯消元
用于解多元一次方程组
优点:
1.回带比原版高斯消元少,速度更快(一般情况下)
2.精度更好
3.代码实现更简单 ---
代码如下:模板P3389
#include<bits/stdc++.h>
using namespace std;
#define file(a) freopen(#a".in","r",stdin),freopen(#a".out","w",stdout)
#define N 110
#define eps 1e-7
int n;
double a[N][N];
inline void Swap(double &x,double &y)
{
double tmp=x;x=y;y=tmp;
}
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]);
}
}
for(int i=1;i<=n;++i)
{
int maxn=i;
for(int j=i+1;j<=n;++j)
{
if(fabs(a[j][i])>fabs(a[maxn][i]))
{
maxn=j;
}
}
if(i!=maxn and !a[maxn][i])
for(int j=1;j<=n+1;++j)
{
Swap(a[i][j],a[maxn][j]);
}
if(fabs(a[i][i])<eps)
{
printf("No Solution");
return 0;
}
for(int j=1;j<=n;++j)
{
if(j==i) continue;
double tmp=a[j][i]/a[i][i];
for(int k=1;k<=n+1;++k)
{
a[j][k]-=a[i][k]*tmp;
}
}
}
for(int i=1;i<=n;++i)
{
printf("%.2lf\n",a[i][n+1]/a[i][i]);
}
return 0;
}
但是显然也是有缺点的
1.容易被圣饼的出题人用圣饼数据卡掉
2.不易判断无解和无数解的情况 ---
对于缺点2可以采用原版高斯消元 不过由于我不会写原版(实际上是没有找到学习资料),并且为了防止出题人造毒瘤数据卡,我们运用 随机化消元
打乱矩阵,防止被卡
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define file(a) freopen(#a".in","r",stdin),freopen(#a".out","w",stdout)
#define N 110
int n;
double a[N][N],ans[N];
inline void Swap(double &x,double &y)
{
double tmp=x;x=y;y=tmp;
}
bool flag=0,ff=0;
int main()
{
srand(time(NULL));
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
for(int j=1;j<=n+1;++j)
{
scanf("%lf",&a[i][j]);
}
}
for(int o=1;o<=10;++o)//这个可以根据题目调整
{
for(int i=1;i<=n;++i)
{
for(int j=i+1;j<=n;++j)
{
int x=rand();
if(x&1)
{
for(int k=1;k<=n+1;++k)
{
Swap(a[i][k],a[j][k]);
}
}
}
}
}
for(int i=1;i<=n;++i)
{
int maxn=i;
for(int j=i+1;j<=n;++j)
{
if(fabs(a[j][i])>fabs(a[maxn][i]))
{
maxn=j;
}
}
if(!a[maxn][i])
{
continue;
}
for(int j=1;j<=n+1;++j)
{
Swap(a[i][j],a[maxn][j]);
}
for(int j=1;j<=n;++j)
{
if(j==i) continue;
double tmp=a[j][i]/a[i][i];
for(int k=1;k<=n+1;++k)
{
a[j][k]-=a[i][k]*tmp;
}
}
}
for(int i=1;i<=n;++i)
{
if(a[i][i]==0)
{
if(a[i][n+1])
{
printf("-1\n");//无解
return 0;
}
else
{
flag=1;
}
continue;
}
ans[i]=a[i][n+1]/a[i][i];
if(!ans[i]) ans[i]=0.00;
}
if(flag)
{
printf("0\n");//无数解
return 0;
}
for(int i=1;i<=n;++i)
{
printf("x%d=",i);
printf("%.2lf\n",ans[i]);
}
return 0;
}