[問題解決] Luogu P2455 [SDOI2006]線形方程式

移動:自分のブログ

トピック

Luogu P2455 [SDOI2006]線形方程式

回答

この質問は、特別な判断を伴う通常のガウス消去法に基づいています。除去の代わりに、係数がすべて0で定数が0でない場合、解決策はありません。ガウス消去アルゴリズムが終了すると、方程式系に解があることを確認できます。このとき、方程式の係数と定数がすべて0であれば、無限解になります。

コード

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100+5;
const double eps=1e-6;	//误差范围 
int n;
double a[maxn][maxn];
inline void gauss()
{
	for(int i=1;i<=n;i++)  //加减消元 
	{
		int mx=i; for(int j=i+1;j<=n;j++) if(fabs(a[j][i])>fabs(a[mx][i])) mx=j;
		if(fabs(a[mx][i])<=eps) continue;
		if(mx!=i) for(int j=i;j<=n+1;j++) swap(a[i][j],a[mx][j]);
		for(int j=i+1;j<=n;j++)
			for(int k=n+1;k>=i;k--) 
				a[j][k]-=a[j][i]/a[i][i]*a[i][k];
	}
	for(int i=n;i>=1;i--)  //代入消元
	{
		for(int j=i+1;j<=n;j++)  
		{
			bool get=1; //get=1表示第j个主元被解了出来 
			if(fabs(a[j][j])<eps) get=0;
			for(int k=j+1;k<=n;k++) if(fabs(a[j][k])>eps) get=0;
			if(get) a[i][n+1]-=a[i][j]*a[j][n+1],a[i][j]=0;  
		}
		if(fabs(a[i][n+1])>eps)	//判无解 
		{
			bool all0=1; //all0=1表示系数全为0 
			for(int j=i;j<=n;j++) if(fabs(a[i][j])>eps) {all0=0; break;}
			if(all0) {printf("-1\n"); return;}
		}
		if(fabs(a[i][i])>eps) a[i][n+1]/=a[i][i]; //注意加判断,0/0=nan,会导致接下来的判断无穷解出错 
	}
	for(int i=1;i<=n;i++) 
	{
		bool all0=1; //all0=1表示系数和常数全为0 
		for(int j=1;j<=n+1;j++) if(fabs(a[i][j])>eps) {all0=0; break;}
		if(all0) {printf("0\n"); return;}
	}
	for(int i=1;i<=n;i++) printf("x%d=%.2lf\n",i,a[i][n+1]); 
}	  
				
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;
}

おすすめ

転載: blog.csdn.net/zjgmartin/article/details/108389872