Gauss 高斯消元
高斯消元…… (裸的暴力)
如果你有一个n元的方程组你会怎么办?
Ans:直接用初中的解方程组的方法呀!
没错,直接暴力加减消元。那什么是“高斯消元”?说白了,就是普通的加减消元罢了。
本人再考场上打了一个暴力解方程,大家都说要高斯消元,弄得我方极了,最后才发现我打的暴力就是高斯消元
流程
- 选其中一个方程
- 将其他方程的其中一个元与选出的方程统一系数
- 将选出的方程与其他方程相减,消去一个未知数,得到 n-1 个 n-1 元的方程组
- 重复之前的步奏,知道只剩一个一元一次的方程
- 求出解,将解一步步往回带,得出所有的解
代码实现
洛谷模板题:P3389 【模板】高斯消元法
1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 using namespace std; 5 6 int n; 7 double a[105][105],b[105],c[105]; 8 //a为方程组,b为常数项,c为解 9 10 void gauss(){ //高斯消元 11 for(int i=1;i<=n;i++){ 12 for(int j=i+1;j<=n;j++){ 13 double s=a[i][n-i+1]/a[j][n-i+1]; 14 for(int k=1;k<=n;k++)a[j][k]*=s; 15 for(int k=1;k<=n;k++)a[j][k]-=a[i][k]; 16 b[j]=b[j]*s-b[i]; 17 } 18 } 19 if(-1e-4<=a[n][1]&&a[n][1]<=1e-4)//double 会有精度误差 20 printf("No Solution"),exit(0);//系数为0,没有唯一解 21 c[1]=b[n]/a[n][1]; 22 for(int i=n-1;i>=1;i--){ 23 for(int j=1;j<=n-i;j++) 24 b[i]-=a[i][j]*c[j]; 25 if(-1e-4<=a[i][n-i+1]&&a[i][n-i+1]<=1e-4) 26 printf("No Solution"),exit(0); //同上 27 c[n-i+1]=b[i]/a[i][n-i+1]; 28 } 29 } 30 31 int main(){ 32 scanf("%d",&n); 33 for(int i=1;i<=n;i++){ 34 for(int j=1;j<=n;j++) 35 scanf("%lf",a[i]+j); 36 scanf("%lf",b+i); 37 } 38 gauss(); 39 for(int i=1;i<=n;i++)printf("%.2f\n",c[i]); 40 }
时间复杂度O(n3),这不就是人人都能想出的大暴力吗?