[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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章