acwing 883 高斯消元解线性方程组

tech2022-08-07  137

题目地址

模拟初等行变换就可以了。

有很多种模拟,对于此题方便,有了这个模拟。

从第一列开始,枚举未处理的行找到最大的主元素。 交换最大主元素的行和当前行。

如果最大主元素也为0,则不处理。

把主元素的系数化为1.

把其他未处理行的主元素列的系数都消去。

继续处理,知道最后一列。

之后特判r是否把所有列处理完,没有在判断是否无解还是多解。 有则把每个x算出来。

代码上有许多步骤解释

#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #include<iostream> #include<algorithm> #include<cstring> #include<cmath> #include<queue> #include<iomanip> #include<cstdio> #define int long long #define sc scanf #define pf printf using namespace std; typedef pair<int,int> pii; typedef long long ll; typedef unsigned long long LL; const int INF = 0x3f3f3f3f; const double eps = 1e-8; const int mod = 10000; const int N = 210; double a[N][N]; int gauss(int n){ int c,r; for(c=1,r=1;c<=n;c++){//从第一列开始 ,r记录当前处理的行。 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+1;i++) swap(a[r][i],a[t][i]);//把最大主元素的交换上去。 for(int i=n+1;i>=c;i--) a[r][i] /= a[r][c];//使当前行的主元素的系数为1,、 //其他的系数也跟着变化,只需进行到当前列因为 前面的都为0了 for(int i=r+1;i<=n;i++)//从当前行的下一行开始,把所有当前列的元素变为0,其他的系数也跟着变, if(fabs(a[i][c]) > eps)//为0就不用消去了 for(int j=n+1;j>=c;j--) a[i][j] -= a[r][j] * a[i][c];//表示系数的消去。 r ++;//处理的行数加1. } if(r <= n){ for(int i=r;i<=n;i++) if(fabs(a[i][n+1]) > eps)//r表示最后处理到这行时为全部的系数都为0,我们从 r行开始,判断是否有 0 == 1的情况 return 2; return 1; } //从后往前 依次消去那一行除了主元素之外的未知数。a[i][n+1]剩下的就是 1*x_ = a[i][n+1]。 for(int i=n-1;i>0;i--){ for(int j=i+1;j<=n;j++) a[i][n+1] -= a[j][n+1] * a[i][j]; } return 0; } signed main(){ // IOS; #ifdef ddgo freopen("C:/Users/asus/Desktop/ddgoin.txt","r",stdin); #endif int n; cin>>n; for(int i=1;i<=n;i++) for(int j=1;j<=n+1;j++) cin>>a[i][j]; int t = gauss(n); if(t == 0) for (int i=1;i<=n;i++) pf("%.2lf\n", a[i][n+1]); else if(t == 1) puts("Infinite group solutions"); else puts("No solution"); return 0; }
最新回复(0)