社区讨论
样例不过求调
P3389【模板】高斯消元法参与者 2已保存回复 3
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 3 条
- 当前快照
- 1 份
- 快照标识符
- @mhj3kdfk
- 此快照首次捕获于
- 2025/11/03 20:09 4 个月前
- 此快照最后确认于
- 2025/11/03 20:09 4 个月前
CPP
#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-6; // 避免精度问题
double a[105][105];
void solve()
{
int n; cin >> n;
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= n + 1; j ++){ // 第n+1列存的是等号右边的常数(消完元之后就是方程的解)
cin >> a[i][j];
}
}
for(int i = 1; i <= n; i ++){
// 找到所有行中系数最大的x[i](主元),并把它交换到第i行。因为消元时每个式子都要乘上 a[j][i]/a[i][i],分母越大误差就会越小
int maxp = i;
for(int j = i + 1; j <= n; j ++){
if(fabs(a[j][i]) - fabs(a[maxp][i]) > eps){ // a[j][i]>a[maxp][i]
maxp = j;
}
}
for(int j = 1; j <= n + 1; j ++){
swap(a[i][j], a[maxp][j]);
}
if(fabs(a[i][i]) < eps){ // a[i][i]==0
// 1.无解 矩阵最后一行出现系数都为0但等式右边不为0(n*n方程组必须对角线所有都不为0) 2.无穷多解 有一行全部为0,此时n个未知数只有n-1个方程,故有无穷多解
cout << "No Solution\n"; return ;
}
for(int j = n + 1; j >= i; j --){ // 把当前行x[i]的系数化一(第i列之前的系数已经都是0,就不用管了)
a[i][j] = a[i][j] / a[i][i];
}
for(int j = 1; j <= n; j ++){ // 消去其他行中的x[i]
if(i != j){
for(int k = 1; k <= n + 1; k ++) a[j][k] -= a[i][k] * (a[j][i] / a[i][i]);
}
}
// for(int i = 1; i <= n; i ++){
// for(int j = 1; j <= n + 1; j ++){
// cerr << a[i][j] << ' ';
// }
// cerr << '\n';
// }cerr << '\n';
}
for(int i = 1; i <= n; i ++){
cout << fixed << setprecision(2) << a[i][n + 1] << '\n'; // 输出等号右边的常数就是解(因为消元后最后一个x[n]化为0,a[n][n+1]就是x[n]的值,向上回代同理)
}
}
signed main()
{
ios :: sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
solve();
return 0;
}
回复
共 3 条回复,欢迎继续交流。
正在加载回复...