bzoj 3503: [Cqoi2014]和谐矩阵
来源:互联网 发布:淘宝客推广个多少钱 编辑:程序博客网 时间:2024/05/14 02:18
题意
我们称一个由0和1组成的矩阵是和谐的,当且仅当每个元素都有偶数个相邻的1。一个元素相邻的元素包括它本身,及他上下左右的4个元素(如果存在)。
给定矩阵的行数和列数,请计算并输出一个和谐的矩阵。注意:所有元素为0的矩阵是不允许的。
题解
算是一道好题吧。
假如对每个点都当一个未知量,那么直接异或方程就好了。
对于不能全0,可以当成一开始全是一,然后变0(然而数据并没有卡)
然后
其实只要第一行确定,后面的都确定了。
就是:
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 longusing 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"); }}
阅读全文