Miraclys

一言(ヒトコト)

洛谷P3389 【模板】高斯消元法

\(\Large\textbf{Description:}\) \(\large{给定一个线性方程组,对其求解。}\)

一道板子题。

\(\Large\textbf{Solution:}\)\(\large{如果我们有这样一个方程组。}\)

x-2y+3z=6
4x-5y+6z=12
7x-8y+10z=21

\(\large{然后高斯消元法只与系数有关,那么我们可以把这个方程组记为:}\)

1 -2 3 6
4 -5 6 12
7 -8 10 21

\(\large{如果我们想解这个方程组,我们希望它变为这种形式:}\)

1 0 0 a
0 1 0 b
0 0 1 c

\(\large{这样子方程的解就可以表示为 x = a, y = b, z = c。那么我们就要一步一步把未知数的系数消去,对于第i列,我们从第i行开始,}\)

\(\large{找到每一行第i列的系数绝对值最大的一行,然后把这一行系数化一下,重复。}\)

\(\Large\textbf{Code:}\)

#include <cstdio>
#include <algorithm>
#define LL long long
#define gc() getchar()
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define _rep(i, a, b) for (int i = (a); i >= (b); --i)
using namespace std;
const int N = 105;
int n;
double eps = 1e-7, ans[N], a[N][N];

inline int read() {
	char ch = gc();
	int ans = 0;
	while (ch > '9' || ch < '0') ch = gc();
	while (ch >= '0' && ch <= '9') ans = (ans << 1) + (ans << 3) + ch - '0', ch = gc();
	return ans;
}

inline double fabs(double x) {
	return x < 0 ? -x : x;
}

int main() {
	n = read();
	rep(i, 1, n) rep(j, 1, n + 1) scanf("%lf", &a[i][j]);
	rep(i, 1, n) {
		int cur = i;
		rep(j, i + 1, n) if (fabs(a[cur][i] < fabs(a[j][i]))) cur = j;
		if (fabs(a[cur][i]) < eps) { printf("No Solution\n"); return 0; }
		if (i != cur) swap(a[i], a[cur]);
		double div = a[i][i];
		rep(j, i ,n + 1) a[i][j] /= div;
		rep(j, i + 1, n) {
			div = a[j][i];
			rep(k, i, n + 1) a[j][k] -= a[i][k] * div;
		}
	}
	ans[n] = a[n][n + 1];
	_rep(i, n - 1, 1) {
		ans[i] = a[i][n + 1];
		rep(j, i + 1, n) ans[i] -= (a[i][j] * ans[j]);
	}
	rep(i, 1, n) printf("%.2lf\n", ans[i]);
	return 0;
} 

\(\large\color{pink}{by}\) \(\large\color{pink}{Miraclys}\)

posted @ 2020-02-05 12:30  Miraclys  阅读(125)  评论(0编辑  收藏  举报

关于本博客样式

部分创意和图片借鉴了

BNDong

的博客,在此感谢