BZOJ_3503_[Cqoi2014]和谐矩阵_高斯消元
BZOJ_3503_[Cqoi2014]和谐矩阵_高斯消元
题意:
我们称一个由0和1组成的矩阵是和谐的,当且仅当每个元素都有偶数个相邻的1。一个元素相邻的元素包括它本身,及他上下左右的4个元素(如果存在)。给定矩阵的行数和列数,请计算并输出一个和谐的矩阵。注意:所有元素为0的矩阵是不允许的。
分析:
设n*m个未知数,列n*m个方程
高斯消元解方程,注意全零矩阵不合法
那我们如果发现有自由元就将它们置为1就好了
代码:
#include <stdio.h> #include <string.h> #include <algorithm> #include <queue> using namespace std; #define p(x,y) ((x-1)*m+y) int a[1700][1700]; int n,m; int tx[]={-1,0,0,0,1}; int ty[]={0,-1,0,1,0}; int which[1700*1700],ins[1700*1700]; void build(){ int i,j,k; for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ for(k=0;k<5;k++){ int dx=i+tx[k],dy=j+ty[k]; if(dx>=1&&dx<=n&&dy>=1&&dy<=m){ a[p(i,j)][p(dx,dy)]=1; } } } } } void Guass(){ int i=1,j=1,k,p; while(i<=n*m&&j<=n*m){ for(k=i;k<=n*m;k++){ if(a[k][j])break; } if(a[k][j]){ if(k!=i){ for(p=j;p<=n*m+1;p++){ swap(a[k][p],a[i][p]); } } for(k=i+1;k<=n*m;k++){ if(a[k][j]){ for(p=j;p<=n*m+1;p++){ a[k][p]^=a[i][p]; } } } which[i]=j; ins[j]=i; i++; } j++; } if(i>n*m)return ; int id=i; for(k=1;k<=n*m;k++){ if(!ins[k]){ which[id]=k; ins[k]=id++; } } for(k=i;k<=n*m;k++){ a[k][n*m+1]=1; } for(k=i-1;k;k--){ for(p=which[k]+1;p<=n*m;p++){ if(a[k][p]){ a[k][n*m+1]^=a[ins[p]][n*m+1]; } } } } int main(){ scanf("%d%d",&n,&m); build(); Guass(); int i,j; for(i=1;i<=n;i++){ int f=0; for(j=1;j<=m;j++){ if(!f)f= printf("%d",a[ins[p(i,j)]][n*m+1]); else printf(" %d",a[ins[p(i,j)]][n*m+1]); } puts(""); } }