poj1681 Painter's Problem 高斯消元

来源:互联网 发布:电子琴知乎 编辑:程序博客网 时间:2024/04/29 01:40
题目链接:http: //poj.org/problem?id=1681


开关的问题,找出各个开关的关系,用高斯消元法。之前f[][]忘记了初始化,检查了快两个小时。。。。。。。。

代码如下:


#include<iostream>#include<cstdio>#define maxn 300using 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;elsef[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");elseprintf("%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");}}