文章目录
一、前言
二、算法
模板:
c++
/*
*功能: 列选主元消元法
*@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优化版本见收藏夹,感觉那个才算是正解
代码:
c
#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!=0
for(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]);
// }
}