链接:
A - Matrix Equation
题意:
给一个 A 矩阵 一个 B 矩阵(矩阵元素为 0 或 1),求有多少个 C 矩阵 满足 A X C = B . C (叉乘 和 点乘)。
思路:
- 赛中发现样例答案都是 2 的幂次 ,然后盲猜答案是二的幂次,队友暴力打了个表发现确实如此,然后随机造了一些样例发现答案好像是把某些 位置看成 一 块,然后就可以 把这一块全部取 0 或 1.然后慢慢的又发现 每一列可以单独考虑求有几个块 。(由于线代只实在学得菜 + 不知道高斯消元是什么 ,赛后才知道这就是所谓的自由元)。然后就开始自闭了,中间甚至连方程都推了,奈何实在是不知道高斯消元这个神奇的东西。然后就铜尾了(第 209 属实幸运)。。。
- 然后这题其实就是每一列单独考虑,然后列出方程组,稍微化简一下就是高斯消元求异或方程组自由元的题了
就变成了上面的形式,就可以直接套模板了推荐一篇博客 高斯消元
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e2 + 7;
const int mod = 998244353;
int a[maxn][maxn];//增广矩阵
int x[maxn];//解集
int freeX[maxn];//自由变元
int n;
int A[maxn][maxn],B[maxn][maxn];
ll poww(ll a,ll b){
ll ans=1;
while(b > 0){
if(b & 1) ans = ans * a % mod;
a = a * a % mod;
b >>= 1;
}
return ans;
}
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];
}
}
}
}
for(int i=row;i<equ;i++)
if(a[i][col]!=0)
return -1;
int temp=var-row;//自由变元有var-row个
if(row<var)//返回自由变元数
return temp;
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);
for(int i = 0; i < n; i ++){
for(int j = 0; j < n; j ++){
scanf("%d",&A[i][j]);
a[i][j] = 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 r = 0;r < n; r ++){
init();
for(int i = 0; i < n; i ++){
a[i][i] = (A[i][i] - B[i][r] + 2) % 2;
}
int freeNum=Gauss(n,n);//获取自由元
if(freeNum == -1) continue;
ans = (ans * poww(2 , freeNum)) % mod;
}
printf ("%lld\n",ans);
return 0;
}