#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
#pragma warning(disable:4996)
const int N = 110;
const double eps = 1e-8;
double a[N][N];
int n;
int gauss() {
int r , c ;
for (r = 0, c = 0; c < n; c++) {
//遍历每一列
int t = r;
//第一步
for (int i = r; i < n; i++)
if (fabs(a[i][c]) > fabs(a[t][c]))
t = i;//找到这一列中绝对值最大的那一行换到最上面
if (fabs(a[t][c]) < eps)continue;//如果这一行的开头已经是0那就不处理这一行
for (int i = c; i <= n; i++)swap(a[t][i], a[r][i]);
//第二步
for (int i = n; i >= c; i--)a[r][i] /= a[r][c];//将当前行的第一个数变成1
//要从最后一列开始 否则前面全是1
//第三步
for (int i = r + 1; i < n; i++) {
//消去这一行下的每一列
if (fabs(a[i][c]) > eps) {//当开头数不是0时才进行处理
for (int j = n; j >= c; j--) {
a[i][j] -= a[i][c] * a[r][j];
//终于想通 a[r][c]已经变成1 那么倍数一定是这一行的开头*a[r][c]=a[i][c]
//然后每一列都减去上一列的倍数即可
}
}
}
r++;//处理下一行
//这里为什么不直接在最外层for写呢 是因为上面有个如果开头=0那就continue下一列 不能直接跳到下一行
}
//第四步
if (r < n) {
//如果不是满秩矩阵
for (int i = r; i < n; i++) {
if (fabs(a[i][n]) > eps)return 2;//如果有一行的b不等于0那就说明存在0!=0的情况 无解
}
return 1;
}
//有解
for (int i = n-1; i >= 0; i--) {
for (int j = i+1; j < n; j++) {
a[i][n] -= a[j][n] * a[i][j];//倒着向上推出结果
//只要最后一行b的结果就行
//n-1行的b=没有-之前的a[i][n]-n行的b * n-1行中对应位置的数(倍数
}
}
return 0;
}
int main() {
scanf("%d", &n);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n + 1; j++) {
scanf("%lf", &a[i][j]);
}
}
int t = gauss();
if (t == 2) puts("No solution");
else if (t == 1)puts("Infinite group solutions");
else {
for (int i = 0; i < n; i++) {
if (fabs(a[i][n]) < eps) a[i][n] = 0; // 去掉输出 -0.00 的情况
printf("%.2lf\n", a[i][n]);
}
}
return 0;
}
AcWing883 高斯消元解线性方程组
最新推荐文章于 2024-07-13 13:25:53 发布