[Luogu3389] 【模板】高斯消元法 [高斯消元]

Link
Luogu - https://www.luogu.org/problemnew/show/P3389


#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<cmath>
#include<ctime>
#include<cctype>
using namespace std;
#define R register
const int MAXN = 105;
const double EPS = 1e-8;
int n;
double Matrix[MAXN][MAXN];
void Santianzhineisaleni()
{
	// 枚舉當前列。 
	for (R int k, i = 1; i <= n; ++i)
	{
		// 找到當前列上的係數絕對值最大的那個方程。 
		// 找係數絕對值最大的那個是爲了儘量減少精度誤差。 
		k = i;
		for (R int j = i + 1; j <= n; ++j)
		{
			if (fabs(Matrix[j][i]) > fabs(Matrix[k][i])) k = j;
		} 
		swap(Matrix[i], Matrix[k]);
		
		// 無解 
		if (fabs(Matrix[i][i]) < EPS)
		{
			// 其實分兩種情況 
			// 無解→有至少一行爲 [0,0,0...,0,x]
			// 有無窮個解→有至少一行爲 [0,0,0,...,0,0] 有幾行就有幾個自由變元 
			puts("No Solution");
			exit(0);
		}
		
		// 把當前行當前列搞成一 然後順便當前行都要跟着被除 
		for (R int j = i + 1; j <= n + 1; ++j)
		{
			Matrix[i][j] /= Matrix[i][i];
		}
		
		// 然後把別的方程都消了。 
		for (R int j = 1; j <= n; ++j)
		{
			if (i == j) continue;
			for (R int k = i + 1; k <= n + 1; ++k)
			{
				Matrix[j][k] -= Matrix[j][i] * Matrix[i][k];
			}
		}
		// 消完如果忽略最後一列的話,假如有解則會得到一個單位矩陣。 
		// 最後一列每一行對應一個變量的值。 
	}
}
int main()
{
	scanf("%d", &n);
	for (R int i = 1; i <= n; ++i)
	{
		for (R int j = 1; j <= n + 1; ++j)
		{
			scanf("%lf", &Matrix[i][j]);
		}
	}
	Santianzhineisaleni();
	for (R int i = 1; i <= n; ++i) printf("%.2f\n", Matrix[i][n+1]);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章