数学_高斯消元+异或方程组

题意:

给一个n * n的矩阵A 和 B,求有多少个矩阵C能使A x C = B ⊙ C???

输入描述:
输入n和01矩阵A01矩阵B

1 <= n <=200

输出描述:
Output the answer module 998244353

输入
2
0 1
1 1
1 0
0 1
输出
2

思路:

对于矩阵C的每一列考虑,其实就是异或方程组的高斯消元

但是在赛场上高斯消元我不会啊…

代码实现:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e2 + 5;
const ll mod = 998244353;

int n;
int A[maxn][maxn];
int B[maxn][maxn];
int a[maxn][maxn];//增广矩阵
int x[maxn];//解集
int freeX[maxn];//自由变元

ll qpow(ll x,ll y){//快速幂
	ll res = 1;
	while(y){
		if(y & 1) res = (res * x) % mod;
		y >>= 1;
		x = (x * x) % mod;
	}
	return res % mod;
}

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){
			for(int j = row;j < var + 1;j++){
				swap(a[row][j],a[maxRow][j]);
			}
		}
		if(a[row][col] == 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++){
					a[i][j] ^= a[row][j];
				}
			}
		}
	}
	for(int i = row;i < equ;i++){
		if(a[i][col] != 0){
			return -1;
		}
	}
	int tmp = var - row;
	if(row < var){
		return tmp;
	}
	return 0;
}
void init(){
	for(int i = 0;i < n;i++){
		for(int j = 0;j < n;j++){
			a[i][j] = A[i][j];
		}
	}
}
int main(){
	scanf("%d",&n);
	memset(a,0,sizeof(a));
	memset(B,0,sizeof(B));
	memset(A,0,sizeof(A));
	for(int i = 0;i < n;i++){
		for(int j = 0;j < n;j++){
			scanf("%d",&A[i][j]);
		}
	}
	for(int i = 0;i < n;i++){
		for(int j = 0;j < n;j++){
			scanf("%d",&B[i][j]);
		}
	}
	ll ans = 1;
	for(int i = 0;i < n;i++){
		init();
		for(int j = 0;j < n;j++){
			a[j][j] = (A[j][j] - B[j][i] + 2) % 2;
		}
		int freeNum = Gauss(n,n);
		if(freeNum == -1) continue;
		ans = (ans * qpow(2,freeNum)) % mod;
	}
	printf("%lld\n",ans);
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值