题目链接:http: //poj.org/problem?id=1681
开关的问题,找出各个开关的关系,用高斯消元法。之前f[][]忘记了初始化,检查了快两个小时。。。。。。。。
开关的问题,找出各个开关的关系,用高斯消元法。之前f[][]忘记了初始化,检查了快两个小时。。。。。。。。
代码如下:
#include<iostream>
#include<cstdio>
#define maxn 300
using namespace std;
int a[maxn][maxn];
int f[maxn][maxn];
int x[maxn];
int n;
int dir[5][2] = { 0, 0, 0, 1, 1, 0, -1, 0, 0, -1 };
int gauss(int n, int m) {
int i, j, k, row, col;
for (row = 0, col = 0; row < n && col < m; row++, col++) {
for (k = row; k < n; k++) {
if (a[k][col] != 0)
break;
}
if (k == n) {
row--;
continue;
}
if (k != row)
for (j = col; j <= m; j++) {
swap(a[k][j], a[row][j]);
}
for (i = row + 1; i < n; i++) {
if (a[i][col])
for (j = col; j <= m; j++)
a[i][j] ^= a[row][j];
}
}
for (i = row; i < n; i++) {
if (a[i][m] != 0)
return -1;
}
int cnt = 0;
for (i = row - 1; i >= 0; i--) {
x[i] = a[i][m];
for (j = m - 1; j > i; j--) {
x[i] ^= (a[i][j] && x[j]);
}
cnt += x[i];
}
return cnt;
}
bool isok(int x, int y) {
if (x < 0 || y < 0 || x >= n || y >= n)
return false;
return true;
}
void init(int n, int m) {
int i, j, k;
for (i = 0; i < n; i++) {
for (j = 0; j < m; j++) {
for (k = 0; k < 5; k++) {
int xx = i + dir[k][0], yy = j + dir[k][1];
if (isok(xx, yy)) {
f[i * m + j][xx * m + yy] = 1;
}
}
}
}
}
void pri();
int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%d", &n);
getchar();
memset(f, 0, sizeof(f));
init(n, n);
int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
char c;
scanf("%c", &c);
if (c == 'w')
f[i * n + j][n * n] = 1;
else
f[i * n + j][n * n] = 0;
}
getchar();
}
memcpy(a, f, sizeof(f));
int ans = gauss(n * n, n * n);
if (ans == -1)
printf("inf\n");
else
printf("%d\n", ans);
// pri();
}
return 0;
}
void pri() {
int i, j;
for (i = 0; i < n; i++) {
for (j = 0; j < n; j++) {
printf("%d ", x[i * n + j]);
}
printf("\n");
}
}