高斯消元(求阶梯矩阵,矩阵的秩,解线性方程组)
今天正在学概率dp,在大佬的博客上看到了高斯消元(由于本蒟蒻实在是什么都不懂) 好奇去百度了一下,发现就是手算方程组,然后去洛谷找了个模板题自己手写了一下
题目链接:
https://www.luogu.org/problemnew/show/P3389
很明显高斯消元就是个O(n^3)的暴力算法,这里就不做过多解释了,代码里有少量注释,有线代基础的应该都能看懂
下面贴一下自己手写的消元板子(有局限性,因为题里要求没有唯一解就输出No...所以有特别需要的比如求基础解系的可以自行修改)
1 #include<bits/stdc++.h> 2 3 using namespace std; 4 5 typedef long long LL; 6 typedef double D; 7 D a[105][105]; 8 bool ok = true; 9 D ans[105]; 10 int n; 11 template <typename T> 12 inline void read(T &s){ 13 T t=1; char k=getchar(); s=0; 14 for (;k<'0'||k>'9';k=getchar()) if (k=='-') t=-1; 15 for (;k>='0'&&k<='9';k=getchar ()) s=(s<<1)+(s<<3)+(k^48); 16 s*=t; 17 } 18 inline bool exchange(int j){ 19 for(int i = j + 1; i <= n; i++){ 20 if(a[i][j]) swap(a[i], a[j]); 21 return true; 22 } 23 ok = false;//主元个数小于n, 秩小于n 不存在唯一解 24 return false; 25 } 26 inline void input(){ 27 for(int i = 1; i <= n;++i){ 28 for(int j = 1; j <= n + 1; ++j) { 29 int tem; 30 read (tem); 31 a[i][j] = tem; 32 } 33 } 34 D st = a[1][1]; 35 for(int j = 1; j <= n + 1; ++j){ 36 a[1][j] /= st; 37 } 38 } 39 inline void print(){ 40 for(int i = 1; i <= n; ++i){ 41 printf("%.2lf\n", ans[i]); 42 } 43 } 44 void Gauss() {//高斯消元 类比方程组手算 45 for (int j = 1; j <= n; ++j) { 46 if (a[j][j] || exchange (j)) {//若待消元为0,进行初等行变换 47 //要消的是第j个元 48 D base = a[j][j];//消元用的基础数 49 for (int i = j + 1; i <= n; ++i) {//正在消第i行 50 if (a[i][j]) { 51 D multip = a[i][j] / base;//数乘的倍数 52 for (int k = j; k <= n + 1; ++k) {//进行线性运算消元 53 a[i][k] -= a[j][k] * multip; 54 } 55 } 56 } 57 } 58 if(!ok) { 59 cout << "No Solution"<< endl; 60 return; 61 } 62 } 63 //消元完毕 得到一个上三角矩阵 64 //进行结果讨论和计算 65 for(int i = n; i > 0; --i) { 66 for(int j = n; j > i; --j){ 67 a[i][n + 1] -= a[i][j] * ans[j]; 68 } 69 ans[i] = a[i][n + 1] / a[i][i]; 70 } 71 print(); 72 } 73 int main(){ 74 read(n); 75 input(); 76 Gauss(); 77 return 0; 78 }
(因为是刚入坑的小萌新,只写过半年代码,所以代码风格或者细节问题求轻喷,代码有问题的话也换迎指正)
浙公网安备 33010602011771号