#1195 : 高斯消元·一(模板题)
2016-08-25 20:49
411 查看
题目链接
高斯消元,使用列主元的方法即可。
如果使用浮点数计算的话,要注意精度问题,还有一个题目的讲解有个小问题,我的提问
高斯消元,使用列主元的方法即可。
如果使用浮点数计算的话,要注意精度问题,还有一个题目的讲解有个小问题,我的提问
#include<bits/stdc++.h> using namespace std; #define cl(a,b) memset(a,b,sizeof(a)) #define fastIO ios::sync_with_stdio(false);cin.tie(0); #define LL long long #define pb push_back #define gcd __gcd #define For(i,j,k) for(int i=(j);i<k;i++) #define lowbit(i) (i&(-i)) #define _(x) printf("%d\n",x) const double EPS = 1e-8; const int maxn = 1e3+2000; const int inf = 1 << 28; /* Gauss—Jordan消元算法 a 是增广矩阵,n个未知数,m个方程式 l 是否是自由变元,系数矩阵的秩就是非自由变元的个数,l[i]==true:表示有界变量 res 解空间的维数 返回值:解空间的维数。res=0:唯一解,res=-1无解 */ void out(int n,double a[][maxn]){ for(int i=0;i<n;i++){ for(int j=0;j<=n;j++){ cout<<a[i][j]<<' '; } cout<<endl; } cout<<"---------------"<<endl; } bool isZero(double x){ return fabs(x)<EPS;//think is zero } inline int solve(double a[][maxn],const int&n,const int &m,bool l[],double ans[]){ int res = 0, r = 0; for(int i=0;i<n;i++)l[i] = false; for(int i=0;i<n;i++){ int pv = r; for(int j=r;j<m;j++){ if(fabs(a[j][i]) > fabs(a[pv][i])) pv = j; } if(r != pv) swap(a[r],a[pv]); if(isZero(a[r][i])){ ++res; continue; } for(int j=0;j<m;j++)//化简出对角,该列除r行之外的行的该列为0 if(j != r && !isZero(a[j][i])){ double tmp = a[j][i] / a[r][i]; for(int k=i+1;k<=n;k++){ a[j][k] -= tmp * a[r][k]; } a[j][i] = 0; } l[i] = true; ++r; //debug out(a,n); } //r行以后的是不是存在(0,0...,a)a!=0的情况 for(int i=r;i<m;i++){ if(!isZero(a[i] ))return -1; } //计算每个值 for(int i=0;i<n;i++)if(l[i]) for(int j=0;j<m;j++)if(fabs(a[j][i])>0) ans[i] = a[j] / a[j][i]; return res; } int n,m; double a[maxn][maxn]; bool l[maxn]; double ans[maxn]; int main(){ cin>>n>>m; for(int i=0;i<m;i++){ for(int j=0;j<=n;j++){ cin>>a[i][j]; } } int res = solve(a,n,m,l,ans); if(res==0){ for(int i=0;i<n;i++){ printf("%d\n",(int)round(ans[i])); } } else if(res==-1){ puts("No solutions"); } else puts("Many solutions"); return 0; } /* 2 2 1 2 5 2 1 4 */
相关文章推荐