高斯消元法,对于ACM题目中需要用矩阵快速幂的方面很好用。可以通过打表找到的值,推出系数!!好用。
一、列主元素消元法
//列主元素消元法
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=100;
const int inf=0x7f7f7f7f;
double a[maxn][maxn];
double x[maxn];//解向量
int n;
void Xiao_gauss(int cur)//不交换列
{
if(cur==n)
{
cout<<endl;
for(int i=0;i<n;i++)
{
for(int j=0;j<=n;j++)
printf("%lf ",a[i][j]);
cout<<endl;
}
return;
}
else{
int id=cur;
double max_r=0;
for(int i=cur;i<n;i++)//找到最大值
if(fabs(a[i][cur])>max_r) max_r=fabs(a[i][cur]),id=i;
//cout<<id<<" "<<max_r<<endl;
for(int i=0;i<=n;i++)//两行元素调换
{
double tmp=a[id][i];
a[id][i]=a[cur][i];
a[cur][i]=tmp;
}
for(int i=cur+1;i<n;i++)//除了本行下面的都要减
{
double t=a[i][cur]/a[cur][cur];
for(int j=cur;j<=n;j++)//
{
a[i][j]=a[i][j]-a[cur][j]*t;
//cout<<a[cur][j]<<endl;
}
}
Xiao_gauss(cur+1);
}
}
void f_x()
{
for(int i=n-1;i>=0;i--)
{
double sum=0;
for(int j=i+1;j<=n-1;j++)
sum+=a[i][j]*x[j];
//cout<<sum<<endl;
x[i]=(a[i][n]-sum)/a[i][i];
}
for(int i=0;i<n;i++)
cout<<"x"<<i+1<<"= "<<x[i]<<endl;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
for(int j=0;j<=n;j++)
cin>>a[i][j];
/*for(int j=0;j<n;j++)
a[n+1][j]=j;
a[n+1][n]=0.0;*/
//列消元法。
Xiao_gauss(0);
f_x();
return 0;
}
/*
3
1 2 3 14
0 1 2 8
2 4 1 13
3
0.001 2.000 3.000 1.000
-1.000 3.712 4.623 2.000
-2.000 1.072 5.643 3.000
*/
二、完全主元素消元法
//(2)完全主元素消元法
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=100;
const int inf=0x7f7f7f7f;
double a[maxn][maxn];
double x[maxn];//解向量
int n;
void show()
{
cout<<endl;
for(int i=0;i<=n;i++)
{
for(int j=0;j<=n;j++)
printf("%lf ",a[i][j]);
cout<<endl;
}
return;
}
void Xiao_gauss(int cur)//完全
{
if(cur==n)
{
show();
return;
}
else{
int id_i=cur;
int id_j=cur;
double max_r=0;
for(int i=cur;i<n;i++)//找到所有最大值
for(int j=cur;j<n;j++)
if(fabs(a[i][j])>max_r)
{
max_r=fabs(a[i][cur]);
id_i=i;
id_j=j;
}
//cout<<id<<" "<<max_r<<endl;
for(int i=0;i<=n;i++)//行元素调换
{
double tmp=a[id_i][i];
a[id_i][i]=a[cur][i];
a[cur][i]=tmp;
}
for(int i=0;i<=n+1;i++)//列元素交换
{
double tmp=a[i][id_j];
a[i][id_j]=a[i][cur];
a[i][cur]=tmp;
}
//cout<<"wanquan"<<endl;
//show();
for(int i=cur+1;i<n;i++)//除了本行下面的都要减
{
double t=a[i][cur]/a[cur][cur];
for(int j=cur;j<=n;j++)//
{
a[i][j]=a[i][j]-a[cur][j]*t;
//a[i][j]=(a[cur][cur]*a[i][j]-a[cur][j]*a[i][cur]);
//a[i][j]/=a[cur][cur];
//cout<<a[i][j]<<endl;
}
}
//cout<<"xiaoyuan"<<endl;
show();
Xiao_gauss(cur+1);
}
}
void f_x()
{
for(int i=n-1;i>=0;i--)
{
double sum=0;
for(int j=i+1;j<=n-1;j++)
sum+=a[i][j]*x[(int)a[n][j]];
//cout<<sum<<endl;
//cout<<id<<endl;
x[(int)a[n][i]]=(a[i][n]-sum)/a[i][i];
}
for(int i=1;i<=n;i++)
cout<<"x"<<i<<"= "<<x[i]<<endl;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
for(int j=0;j<=n;j++)
cin>>a[i][j];
//赋予n+1为x代表
for(int j=0;j<n;j++)
a[n][j]=j+1;
a[n][n]=0;
//列消元法。
Xiao_gauss(0);
f_x();
return 0;
}
/*
3
1 2 3 14
0 1 2 8
2 4 1 13
3
0.001 2.000 3.000 1.000
-1.000 3.712 4.623 2.000
-2.000 1.072 5.643 3.000
*/
三、若尔当,用了列主元素
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
using namespace std;
const int maxn=100;
const int inf=0x7f7f7f7f;
double a[maxn][maxn];
double x[maxn];//解向量
int n;
int gcd(int a,int b)
{
return b?gcd(a,a%b):a;
}
void show()
{
cout<<endl;
for(int i=0;i<n;i++)
{
for(int j=0;j<=n;j++)
printf("%lf ",a[i][j]);
cout<<endl;
}
}
void Xiao_gauss(int cur)//不交换列
{
if(cur==n)
{
show();
return;
}
else{
//lie主元素消元法
/*int id=cur;
double max_r=0;
for(int i=cur;i<n;i++)//找到最大值
if(fabs(a[i][cur])>max_r) max_r=fabs(a[i][cur]),id=i;
//cout<<id<<" "<<max_r<<endl;
for(int i=0;i<=n;i++)//两行元素调换
{
double tmp=a[id][i];
a[id][i]=a[cur][i];
a[cur][i]=tmp;
}*/
int tmp=a[cur][cur];
for(int i=0;i<=n;i++)
{
a[cur][i]/=tmp;//变成1
}
//show();
for(int i=0;i<n;i++)//每行都要操作
{
if(i==cur) continue;
double t=a[i][cur]/a[cur][cur];
for(int j=cur;j<=n;j++)//
{
a[i][j]=a[i][j]-a[cur][j]*t;
//a[i][j]=(a[cur][cur]*a[i][j]-a[cur][j]*a[i][cur])/a[cur][cur];
//cout<<a[cur][j]<<endl;
}
}
//show();
Xiao_gauss(cur+1);
}
}
void f_x()
{
for(int i=n-1;i>=0;i--)
{
//cout<<sum<<endl;
x[i]=a[i][n];
}
for(int i=0;i<n;i++)
cout<<"x"<<i+1<<"= "<<x[i]<<endl;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
for(int j=0;j<=n;j++)
cin>>a[i][j];
Xiao_gauss(0);
f_x();
return 0;
}
/*
3
1 2 3 14
0 1 2 8
2 4 1 13
3
0.001 2.000 3.000 1.000
-1.000 3.712 4.623 2.000
-2.000 1.072 5.643 3.000
3
2 8 2 14
1 6 -1 13
2 -1 2 5
*/