3503: [Cqoi2014]和谐矩阵
Time Limit: 10 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 897 Solved: 411
[ Submit][ Status][ Discuss]
Description
我们称一个由0和1组成的矩阵是和谐的,当且仅当每个元素都有偶数个相邻的1。一个元素相邻的元素包括它本
身,及他上下左右的4个元素(如果存在)。
给定矩阵的行数和列数,请计算并输出一个和谐的矩阵。注意:所有元素为0的矩阵是不允许的。
Input
输入一行,包含两个空格分隔的整数m和n,分别表示矩阵的行数和列数。
Output
输出包含m行,每行n个空格分隔整数(0或1),为所求矩阵。测试数据保证有解。
Sample Input
Sample Output
1 1 1 0
0 0 0 1
1 1 0 1
数据范围
1 <=m, n <=40
解题思路:首先可以知道第一行确定后下面的都可以确定了,
那么可以递推让后用第一行表示最后一行,这样就列出了n个
方程,于是高斯消元,题目中说全0的不算,那么对于那些
自由元就可以设为1。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
int n,m;
int g[60][60],f[60][60][60],h[60][60],ans[60];
bool b[60];
inline int read()
{
char y; int x=0,f=1; y=getchar();
while (y<'0' || y>'9') {if (y=='-') f=-1; y=getchar();}
while (y>='0' && y<='9') {x=x*10+int(y)-48; y=getchar();}
return x*f;
}
void guass()
{
int p=1; int x=1;
while (x<=n)
{
int j=0;
for (int i=p;i<=n;++i)
if (g[i][x]!=0)
{
j=i;
break;
}
if (j==0)
{
ans[x]=1; b[x]=false;
for (int i=1;i<=p-1;++i)
if (g[i][x]==1)
{
g[i][x]=0; g[i][n+1]^=1;
}
++x;
}else
{
for (int i=1;i<=n+1;++i) swap(g[j][i],g[p][i]);
for (int i=p+1;i<=n;++i)
if (g[i][x]==1)
{
for (int k=x;k<=n+1;++k) g[i][k]^=g[p][k];
}
++p; ++x;
}
}
--x;
for (int i=p-1;i>=1;--i)
{
while (b[x]==false)--x;
ans[x]=g[i][n+1]; b[x]=false;
for (int j=i-1;j>=1;--j)
if (g[j][x]!=0)g[j][n+1]^=ans[x],g[j][x]=0;
}
}
int main()
{
memset(b,true,sizeof(b));
m=read(); n=read();
for (int i=1;i<=n;++i) f[1][i][i]=1;
for (int i=2;i<=m+1;++i)
for (int j=1;j<=n;++j)
{
for (int k=1;k<=n;++k)
{
f[i][j][k]=f[i-1][j-1][k]^f[i-1][j][k]^f[i-1][j+1][k]^f[i-2][j][k];
}
}
for(int i=1;i<=n;++i)
for (int j=1;j<=n;++j)
g[i][j]=f[m+1][i][j];
guass();
for (int i=1;i<=n;++i) h[1][i]=ans[i];
for (int i=2;i<=m;++i)
{
for (int j=1;j<=n;++j)
h[i][j]=h[i-1][j]^h[i-1][j+1]^h[i-1][j-1]^h[i-2][j];
}
for (int i=1;i<=m;++i)
{
for (int j=1;j<=n-1;++j)
printf("%d ",h[i][j]);
printf("%d\n",h[i][n]);
}
}