思路
考虑一个点要不要翻,如果它左边的点为 (1),那么它必须翻
所以我们可以从左往右一列一列地翻
先枚举第 (0) 列的状态
然后之后的列就确定了
判断一下最后一列是不是 (0) 就行了
状压快速翻
(Code)
#include<cstdio>
#include<cstring>
using namespace std;
int n , m , t , b[21] , c[21];
int main()
{
scanf("%d%d%d" , &n , &m , &t);
char s[50];
for(; t; t--)
{
memset(c , 0 , sizeof c);
for(register int i = 1; i <= n; i++)
{
scanf("%s" , s);
for(register int j = 0; j < m; j++)
c[j + 1] = (c[j + 1] << 1) + s[j] - '0';
}
int up = (1 << n) - 1 , ans = 0;
for(register int i = 0; i <= up; i++)
{
b[0] = i;
for(register int j = 1; j <= m; j++) b[j] = c[j] & up;
for(register int j = 1; j <= m; j++)
{
b[j] = b[j] ^ b[j - 1] ^ (b[j - 1] << 1) ^ (b[j - 1] << 2) ^ (b[j - 1] >> 1) ^ (b[j - 1] >> 2);
b[j] &= up;
b[j + 1] = (b[j + 1] ^ b[j - 1]) & up;
}
if (b[m] == 0) ans++;
}
printf("%d
" , ans);
}
}