建立方程的过程和poj 1222基本相同
这道题求的是如果能把所有墙都变为黄色所需要的最少操作次数
这里看不明白是怎么做的
在网上找了很多代码。。。但是都没有注释
算了,这个题的意义就在于熟悉建立方程以及解方程的过程
代码如下:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAXN 400
using namespace std;
int equ, var;
int x[MAXN];
int free_x[MAXN];
int a[MAXN][MAXN];
char chs[MAXN*MAXN];
char str[MAXN][MAXN];
void print(int n) {
for(int i=0; i<n; ++i) {
for(int j=0; j<=n; ++j) {
printf("%d ", a[i][j]);
}
puts("");
}
}
int gauss() {
int i, j, k, max_r;
int col = 0;
for(k=0, col=0; k<equ&&col<var; ++k, ++col) {
max_r = k;
for(i=k+1; i<equ; ++i) {
if(a[i][col] > a[max_r][col])
max_r = i;
}
if(max_r != k) {
for(j=0; j<=var; ++j)
swap(a[k][j], a[max_r][j]);
}
if(a[k][col] == 0) {
--k;
continue;
}
for(i=k+1; i<equ; ++i) {
if(a[i][col])
for(j=col; j<=var; ++j)
a[i][j] ^= a[k][j];
}
}
for(int i=k; i<equ; ++i) {
if(a[i][col])
return -1;
}
if(k < var) return var-k;
for(int i=var-1; i>=0; --i) {
x[i] = a[i][var];
for(int j=i+1; j<var; ++j)
x[i] ^= (a[i][j]&&x[j]);
}
return 0;
}
void solve() {
int ans = gauss();
if(ans == -1) {//无解
puts("inf");
return ;
} else if(ans == 0) {//唯一解
int res = 0;
for(int i=0; i<equ; ++i)
res += x[i];
printf("%d\n", res);
return ;
} else {//多解,这里看不懂。。。
int res = 0x3f3f3f3f;
int tot = (1<<ans);
for(int i=0; i<tot; ++i) {
int cnt = 0;
for(int j=0; j<ans; ++j) {
if(i&(1<<j)) {
x[free_x[j]] = 1;
++cnt;
} else x[free_x[j]] = 0;
}
for(int j=var-ans-1; j>=0; --j) {
int idx;
for(idx=j; idx<var; ++idx)
if(a[j][idx])
break;
x[idx] = a[j][var];
for(int l=idx+1; l<var; ++l)
if(a[j][l])
x[idx] ^= x[l];
cnt += x[idx];
}
res = min(res, cnt);
}
printf("%d\n", res);
}
}
int main(void) {
int T, n;
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
equ = var = n*n;
memset(a, 0, sizeof(a));
memset(x, 0, sizeof(x));
memset(free_x, 0, sizeof(free_x));
for(int i=0; i<n; ++i)
scanf("%s", str[i]);
int cnt = 0;
for(int i=0; i<n; ++i)
for(int j=0; j<n; ++j)
chs[cnt++] = str[i][j];
for(int i=0; i<cnt; ++i) {
a[i][i] = 1;
if(i%n != 0) a[i][i-1] = 1;
if(i%n != n-1) a[i][i+1] = 1;
if(i >= n) a[i][i-n] = 1;
if(i < n*n-n) a[i][i+n] = 1;
}
for(int i=0; i<cnt; ++i) {
a[i][n*n] = (chs[i]=='y' ? 0 : 1);
}
//print(n*n);
//solve();
gauss(n*n);
}
return 0;
}