题意
我们称一个由0和1组成的矩阵是和谐的,当且仅当每个元素都有偶数个相邻的1。一个元素相邻的元素包括它本身,及他上下左右的4个元素(如果存在)。
给定矩阵的行数和列数,请计算并输出一个和谐的矩阵。注意:所有元素为0的矩阵是不允许的。
题解
算是一道好题吧。
假如对每个点都当一个未知量,那么直接异或方程就好了。
对于不能全0,可以当成一开始全是一,然后变0(然而数据并没有卡)
然后
O(n3m3)
爆炸。
其实只要第一行确定,后面的都确定了。
就是:
c[i][j]=c[i-1][j]^c[i-1][j-1]^c[i-1][j+1]^c[i-2][j];
然后就是要n+1行全是0,得出第一行每一项对n+1行的贡献(一定是0/1)解异或方程就好了。
code:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<bitset>
#define LL long long
using namespace std;
LL yh[5]={-1,0,1,0};
LL yl[5]={0,1,0,-1};
bitset<45> a[45];
LL n,m,c[45][45];
LL b[45][45];
void guess()
{
for(LL i=1;i<=m;i++)
{
LL j;
for(j=i;j<=m&&!a[j][i];j++);
if(j==m+1) {continue;}
swap(a[i],a[j]);
for(LL k=i+1;k<=m;k++)
if(a[k][i]) a[k]^=a[i];
}
for(LL i=m;i>=1;i--)
{
if(!a[i][i]) {c[1][i]=1;continue;}
for(LL j=i;j<=m;j++) a[i][m+1]=a[i][m+1]^(c[1][j]*a[i][j]);
c[1][i]=a[i][m+1];
}
}
int main()
{
scanf("%lld %lld",&n,&m);
for(LL i=1;i<=m;i++) b[1][i]=1LL<<(i-1);
for(LL i=2;i<=n+1;i++)
for(LL j=1;j<=m;j++) b[i][j]=b[i-1][j-1]^b[i-1][j]^b[i-1][j+1]^b[i-2][j];
for(LL i=1;i<=m;i++)
for(LL j=1;j<=m;j++)
a[i][j]=(b[n+1][i]>>(j-1)&1LL);
guess();
for(LL i=2;i<=n;i++)
for(LL j=1;j<=m;j++) c[i][j]=c[i-1][j]^c[i-1][j-1]^c[i-1][j+1]^c[i-2][j];
for(LL i=1;i<=n;i++)
{
for(LL j=1;j<=m;j++) printf("%lld ",c[i][j]);
printf("\n");
}
}