您的位置:首页 > 其它

#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
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: