3503: [Cqoi2014]和谐矩阵
Time Limit: 10 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1101 Solved: 507
[ Submit][ Status][ Discuss]
Description
我们称一个由0和1组成的矩阵是和谐的,当且仅当每个元素都有偶数个相邻的1。一个元素相邻的元素包括它本
身,及他上下左右的4个元素(如果存在)。
给定矩阵的行数和列数,请计算并输出一个和谐的矩阵。注意:所有元素为0的矩阵是不允许的。
Input
输入一行,包含两个空格分隔的整数m和n,分别表示矩阵的行数和列数。
Output
输出包含m行,每行n个空格分隔整数(0或1),为所求矩阵。测试数据保证有解。
Sample Input
4 4
Sample Output
0 1 0 0
1 1 1 0
0 0 0 1
1 1 0 1
如果第一排确定了,那么后面所有数字都确定了
所以可以暴力枚举第一排的所有情况,然后看第m+1行是不是全是0
全是0就是一组合法解,复杂度O(nm2^n)不行
考虑建立一个方程组:
如果第1行第c个数字是1会导致第m+1行第d个数为1,那么a[d][c]=1,否则a[d][c]=0
之后对这个矩阵高斯消元求出的所有合法的解就一定是第一行合法的状态
为了避免全是0的情况,自由元全部默认为1
复杂度O(m^3)
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[50][50], b[50][50], c[50][50];
void Guass(int m)
{
int t, k, i, j;
for(i=1;i<=m;i++)
{
t = i;
while(t<=m && a[t][i]==0)
t++;
if(t>m)
continue;
for(j=1;j<=m;j++)
swap(a[i][j], a[t][j]);
for(j=i+1;j<=m;j++)
{
if(a[j][i])
{
for(k=i;k<=m;k++)
a[j][k] ^= a[i][k];
}
}
}
for(i=m;i>=1;i--)
{
if(a[i][i])
c[1][i] = a[i][m+1];
else
c[1][i] = 1;
for(j=1;j<=i-1;j++)
{
if(a[j][i])
a[j][m+1] ^= c[1][i];
}
}
}
int main(void)
{
int i, j, k, n, m;
scanf("%d%d", &n, &m);
for(i=1;i<=m;i++)
{
b[1][i] = 1;
for(j=2;j<=n+1;j++)
{
for(k=1;k<=m;k++)
b[j][k] = b[j-1][k]^b[j-1][k-1]^b[j-2][k]^b[j-1][k+1];
}
for(j=1;j<=m;j++)
a[j][i] = b[n+1][j];
memset(b, 0, sizeof(b));
}
Guass(m);
for(i=2;i<=n;i++)
{
for(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(i=1;i<=n;i++)
{
for(j=1;j<=m;j++)
{
if(j>=2)
printf(" ");
printf("%d", c[i][j]);
}
puts("");
}
return 0;
}