高斯消元矩阵
文章目录
- 一、前言
- 二、算法
- 1.Matrix Equation
- 三、总结
一、前言
二、算法
模板:
/*
*功能: 列选主元消元法
*@Author: lzyws739307453
*@Language: C++
*@File Name: Gauss.cpp
*@Create Time: 2019年05月05日 星期日
*/
#include <bits/stdc++.h>
using namespace std;
const int MAXN = 5;
//输出矩阵
void printM(double a[][MAXN], int n) {for (int i = 1; i <= n; i++) {for (int j = 1; j <= n + 1; j++)printf("%10f,", a[i][j]);printf("\n");}
}
//选择列主元并进行消元
void SelectColE(double a[][MAXN], int n) {double temp; //用于记录消元时的因数for (int i = 1; i <= n; i++) {int r = i;for (int j = i + 1; j <= n; j++)if (fabs(a[j][i]) > fabs(a[r][i]))r = j;if (r != i)for (int j = i; j <= n + 1; j++)swap(a[i][j], a[r][j]);//与最大主元所在行交换for (int j = i + 1; j <= n; j++) {//消元temp = a[j][i] / a[i][i];for (int k = i; k <= n + 1; k++)a[j][k] -= a[i][k] * temp;}printf("第%d列消元后:\n", i);printM(a, n);}
}
//高斯消元法(列选主元)
void Gauss(double a[][MAXN], int n) {SelectColE(a, n);//列选主元并消元成上三角printf("上三角的结果:\n");printM(a, n);for (int i = n; i >= 1; i--) {//回代求解for (int j = i + 1; j <= n; j++)a[i][n + 1] -= a[i][j] * a[j][n + 1];a[i][n + 1] /= a[i][i];}
}
//测试函数
int main() {double a[5][MAXN] = {{0, 0, 0, 0, 0},{0, 2, 1, -1, 8},{0, -3, -1, 2, -11},{0, -2, 1, 2, -3}};Gauss(a, 3);//3个方程3个未知数for (int i = 1; i <= 3; i++)printf("X%d = %9f\n", i, a[i][4]);return 0;
}
1.Matrix Equation
题解:
bitset优化版本见收藏夹,感觉那个才算是正解
代码:
#include<bits/stdc++.h>using namespace std;
#define int long long
const int mod = 998244353;
const int N = 210;
int a[N][N];//增广矩阵
int x[N];//解集
bool freeX[N];//标记是否为自由变元
int n;
int A[N][N],B[N][N];int Gauss(int equ,int var){//返回自由变元个数/*初始化*/for(int i=0;i<=var;i++){x[i]=0;freeX[i]=0;}/*转换为阶梯阵*/int col=0;//当前处理的列int num=0;//自由变元的序号int row;//当前处理的行for(row=0;row<equ&&col<var;row++,col++){//枚举当前处理的行int maxRow=row;//当前列绝对值最大的行for(int i=row+1;i<equ;i++){//寻找当前列绝对值最大的行if(abs(a[i][col])>abs(a[maxRow][col]))maxRow=i;}if(maxRow!=row){//与第row行交换for(int j=row;j<var+1;j++)swap(a[row][j],a[maxRow][j]);}if(a[row][col]==0){//col列第row行以下全是0,处理当前行的下一列freeX[num++]=col;//记录自由变元row--;continue;}for(int i=row+1;i<equ;i++){if(a[i][col]!=0){for(int j=col;j<var+1;j++){//对于下面出现该列中有1的行,需要把1消掉a[i][j]^=a[row][j];}}}}/*求解*///无解:化简的增广阵中存在(0,0,...,a)这样的行,且a!=0for(int i=row;i<equ;i++)if(a[i][col]!=0)return -1;//无穷解: 在var*(var+1)的增广阵中出现(0,0,...,0)这样的行int temp=var-row;//自由变元有var-row个if(row<var)//返回自由变元数return temp;//唯一解: 在var*(var+1)的增广阵中形成严格的上三角阵for(int i=var-1;i>=0;i--){//计算解集x[i]=a[i][var];for(int j=i+1;j<var;j++)x[i]^=(a[i][j]&&x[j]);}return 0;
}int qpow(int base,int power) {int res = 1;while(power) {if(power & 1) res = res*base%mod;base = base*base%mod;power >>= 1;}return res;
}signed main(){int equ,var;//equ个方程,var个变元cin >> n;equ = n; var = n;for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) cin >> A[i][j];}for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) cin >> B[i][j];}int ans = 1;for (int k = 0; k < n; k++) {//对于c的第几列memset(a,0,sizeof(a));for (int i = 0; i < n; i++) {for (int j = 0; j < n; j++) {a[i][j] = A[i][j];}a[i][n] = 0;if(A[i][i] == B[i][k]) a[i][i] = 0;else a[i][i] = 1;}int freeNum=Gauss(equ,var);//自由元个数ans = ans*qpow(2,freeNum);ans %= mod;}cout << ans << endl;// if(freeNum==-1)//无解
// printf("无解\n");
// else if(freeNum==-2)//有浮点数解无整数解
// printf("无整数解\n");
// else if(freeNum>0){//有无穷多解
// printf("有无穷多解,自由变元个数为%d\n",freeNum);
// for(int i=0;i<var;i++){
// if(freeX[i])
// printf("x%d是自由变元\n",i+1);
// else
// printf("x%d=%d\n",i+1,x[i]);
// }
// }
// else{//有唯一解
// for(int i=0;i<var;i++)
// printf("x%d=%d\n",i+1,x[i]);
// }
}