众所周知,高斯消消乐很好玩(并不),并且理解很简单,代码也很“简单”(蒟蒻到听了n遍还是不会写代码,在此写篇博客记下来)
高斯消元:
高斯消元是用来解线性方程组的,即把一个方程组的系数与方程右边的数写成一个矩阵,再解这个矩阵对应的行列式的值,就可以快速的求解
一个行列式有如下几种初等变换:
1.交换两行(列),行列式的值变号。
2.某行(列)的所有数,同时乘上k,行列式的值不变
3.某行(列)的所有数同时加上a,行列式的值不变
so高斯消元应该怎么消呢?
(高斯消元以列为单位消)
step1:先将第一行第一列的数化为1,并且同一行的数做相同变换
step2:再将其余行的第一列化为0(通过加/减1的k倍),并且同一行的数做相同变换
step3:这时,第一行就处理完了,再将原本的第二行视作新的第一行,且新的第一列为原本的第二列(就是把原来矩阵的第一行第一列扔掉),做相同的变换,一直处理到原本的第n-1行,这样矩阵就消完了。接下来就是回带求解
当然,如果有一行全是0的时候会出现无解或有无穷多解,要特判。
#include<iostream> #include<cstdio> #include<cmath> using namespace std; int n,mo=100000007; double a[1001][1001]; int main() { bool sc=0; scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n+1;j++) scanf("%lf",&a[i][j]); int bj,flag=0; for(int i=1;i<=n;i++) {bj=i; while(a[bj][i]==0&&bj<=n) bj+=1; if(bj==n+1){ flag=1;continue; } for(int j=1;j<=n+1;j++)swap(a[i][j],a[bj][j]);//交换 double kk=a[i][i];//确保对角线上的数是1 for(int j=1;j<=n+1;j++) {a[i][j]/=kk;//其余数跟着处理 } for(int j=1;j<=n;j++) {if(i!=j){double k=a[j][i];//k=这行第一个数 for(int m=1;m<=n+1;m++) {a[j][m]-=k*a[i][m];//此行所有的数减去第一个数*k } } } if(i==n)//消完输出 {for(int j=1;j<=n;j++) {for(int m=1;m<=n+1;m++) cout<<a[j][m]<<" "; cout<<endl; sc=1; } } } if(!sc)printf("False"); }
吐血三升后肝出来的高消
高斯消消乐真好玩QwQ
原文:https://www.cnblogs.com/lcez56jsy/p/10673602.html