[置顶] 【模板】高斯消元
2017-08-13 22:00
316 查看
题目地址:戳这
首先来看一道例题:
3x+2y+z=6
2x+2y+2z=4
4x-2y-2z=2
首先来看一道例题:
3x+2y+z=6
2x+2y+2z=4
4x-2y-2z=2
大家会觉得这到题是初中水题,看一眼就出来了,甚至有些人小学就会了。但是你们有没有想过如果有很多未知数的话怎么办能,手动消元?怎么可能。这复杂度太高了。于是便把目光转向了计算机。没错计算机可以很快的算出答案,但是计算机却没有人类这种思路,不能看题而来,而是去编写一个程序,来面对所有的问题。接下来就用这到题来讲讲高斯消元。 我们用矩阵来进行高斯消元。先把方程写成如下形式: _ _ | 3 2 1 6 | | 2 2 2 4 | | 4 2 2 2 | — - 第二步对矩阵进行初等变换,初等变换包括如下几个操作: 1.将某行同乘或同除一个非零实数 2.将某一行加到另一行 第三部将矩阵变为上三角矩阵,就是把主对角线全变为1,主对角线下的数都变为零。形式如下: _ _ | 1 2/3 1/3 2 | | 0 1 2 0 | | 0 0 1 -3 | — - 代码如下
#include<cstdio> #include<cstdlib> #include<iostream> using namespace std; double a[101][101],c[101];//如果用float会有精度问题 int main() { int n; cin>>n;//输入 for(int i=1; i<=n; i++) { for(int j=1; j<=n+1; j++) { cin>>a[i][j];//输入 a[i][j]*=1.00;//转化为浮点数,否则除数都会为整 } double o=a[i][1]; for(int j=1; j<=n+1; j++) a[i][j]=a[i][j]*1.0/o;//把每行第一个的值变为1 } for(int i=1; i<=n; i++) { if(a[i][i]==0) { cout<<"No Solution";//不存在唯一解 return 0;//结束 } for(int j=i+1; j<=n+1; ++j) a[i][j]/=a[i][i];//把主对角线的系数化为一 a[i][i]=1; for(int j=i+1; j<=n; j++) {//讲下三角化为0 for(int k=i+1; k<=n+1; k++) a[j][k]-=a[j][i]*a[i][k]; a[j][i]=0; } } for(int i=1; i<=n; i++) { for(int j=1; j<=n+1; j++) cout<<a[i][j]<<" "; cout<<endl; } for(int i=n; i>=1; i--) {//递推求解方程的值 double ans=a[i][n+1]; for(int j=i+1; j<=n; j++) ans-=c[j]*a[i][j]; c[i]=ans/a[i][i];//用c数组存储答案 } for(int i=1; i<=n; i++) printf("%0.2lf\n",c[i]);//输出 return 0; }