真\(\cdot\)高斯消元模板题
由于各种hack数据被造出来~码量突增~,其实也就多了二三十行
将每行系数消到最多有一个非0数
特殊情况:
在过程同时
没有这元了,则表示有无穷解
发现一行系数都为0,但函数值不为0,则表示无解
最后要注意的是,无穷解的前提是有解
#include <iostream>
#include <algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<vector>
using namespace std;
typedef long long LL;
const double eps=1e-8;
double xs[55][55],ans[55];
int n,m,i,j,k;
bool f1=0,f2=0;
inline LL Read(){
LL x=0,f=1; char c=getchar();
while(c<'0'||c>'9'){
if(c=='-') f=-1; c=getchar();
}
while(c>='0'&&c<='9')
x=(x<<3)+(x<<1)+c-'0',c=getchar();
return x*f;
}
int main(){
n=Read();
for(LL i=1;i<=n;i++)
for(LL j=1;j<=n+1;j++)
xs[i][j]=(double)Read();
LL c=1;
for(LL i=1;i<=n;i++){
if(c>n)//每个元都消过了
break;
for(LL j=i;j<=n;++j)
if (abs(xs[j][c])>abs(xs[i][c]))
for(LL k=1;k<=n+1;++k)
swap(xs[i][k],xs[j][k]);
if (fabs(xs[i][c])<eps){//没有该元
f2=1;//无穷解
c++;
i--;//这行消下一元
continue;
}
for(LL j=i+1;j<=n;++j){
double t=xs[j][c]/xs[i][c];
for(LL k=c;k<=n+1;++k)
xs[j][k]-=xs[i][k]*t;
}//消掉
c++;
}
c=n;
for(LL i=n;i>=1;--i){
if(c<1)
break;
if(abs(xs[i][c])<eps)//没有该元
continue;
for(LL j=1;j<=i-1;++j){
double t=xs[j][c]/xs[i][c];
for(LL k=c;k<=n+1;++k)
xs[j][k]-=xs[i][k]*t;
}//其他地方消掉 且不只是改变函数值
c--;
}
for(LL i=n;i>=1;--i){
f1=0;
for(LL j=1;j<=n;++j)
if(fabs(xs[i][j])>eps)
f1=1;
if(f1==0&&fabs(xs[i][n+1])>eps){
puts("-1");
return 0;
}//系数为0 函数值不为0
if(fabs(xs[i][i])>eps)
if (!f2)
ans[i]=xs[i][n+1]/xs[i][i];
}
if (f2==1){
puts("0");
return 0;
}
for(LL i=1;i<=n;++i)
if(fabs(ans[i])<eps)
printf("x%d=0\n",i);
else
printf("x%lld=%.2lf\n",i,ans[i]);
return 0;
}
原文地址:https://www.cnblogs.com/y2823774827y/p/10214568.html
时间: 2024-10-04 18:31:56