POJ1681 高斯消元法 或者枚举 xingxing在努力
这类开关问题一般都有两种解法, 一种是暴力枚举第一行 , 另外一种是列方程求解。。
先附上暴力代码:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; int Map[20][20]; //y->0 w->1 int f[20][20]; int n; int dx[5] = {0, 0, 0, 1, -1}; int dy[5] = {0, 1, -1, 0, 0}; int getcolor(int x, int y) { int col = Map[x][y]; for(int i=0; i<5; i++) { int nx = x+dx[i], ny = y+dy[i]; if(nx>=0&&nx<n&&ny>=0&&ny<n) col += f[nx][ny]; } return col%2; } int solve() //返回值-1表示无解 { for(int i=1; i<n; i++) for(int j=0; j<n; j++) if(getcolor(i-1, j)==1) f[i][j] = 1; for(int j=0; j<n; j++) if(getcolor(n-1, j)==1) return -1; int res = 0; for(int i=0; i<n; i++) for(int j=0; j<n; j++) res += f[i][j]; return res; } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d", &n); for(int i=0; i<n; i++) { char s[20]; scanf("%s", s); for(int j=0; j<n; j++) if(s[j]=='y') Map[i][j] = 0; else Map[i][j] = 1; } int res = -1; for(int i=0; i<(1<<n); i++) //暴力枚举第一行 { memset(f, 0, sizeof(f)); int st = i; for(int j=0; j<n; j++) { if((st&1)==1) f[0][j] = 1; else f[0][j] = 0; st>>=1; } int tp = solve(); if(tp >= 0) { if(res==-1) res = tp; else res = min(res, tp); } } if(res == -1) printf("inf\n"); else printf("%d\n", res); } return 0; }
另外一种则是高斯消元法:代码如下
#include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int maxn = 300; int n; int a[maxn][maxn]; //增广矩阵 int x[maxn]; //解空间 int free_x[maxn], free_num; //自由元以及自由元的个数 int equ, var; //方程的数量 以及变量的个数 void debug() { printf("debug -------------\n"); for(int i=0; i<equ; i++) { for(int j=0; j<=var; j++) printf("%d ", a[i][j]); printf("\n"); } } int gauss() { free_num = 0; int k, col; //当前处理的行(哪一个方程)和列(哪一个变量) for(k=0,col=0; k<equ&&col<var; k++,col++) { int max_r = k; //第col列绝对值的最大值 for(int i=k+1; i<equ; i++) { if(abs(a[i][col]) > abs(a[max_r][col])) max_r = i; } if(max_r != k) //交换第k行和第max_r行 { for(int j=k; j<=var; j++) swap(a[k][j], a[max_r][j]); } if(a[k][col] == 0) //说明该列以下全是0 { k--; free_x[free_num++] = col; continue; } for(int i=k+1; i<equ; i++) { if(a[i][col] != 0) for(int j=col; j<=var; j++) a[i][j] ^= a[k][j]; } } for(int i=k; i<equ; i++) { if(a[i][col] != 0 ) return -1; } int res = 0x3f3f3f3f; for(int i=0; i<(1<<(var-k)); i++) { int cnt = 0; int index = i; for(int j=0; j<var-k; j++) { x[free_x[j]] = (index&1); if(x[free_x[j]]) cnt++; index>>=1; } for(int j=k-1; j>=0; j--) { int tmp = a[j][var]; for(int l=j+1; l<var; l++) if(a[j][l]) tmp ^= x[l]; x[j] = tmp; if(x[j]) cnt++; } if(cnt < res) res = cnt; } return res; } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d", &n); memset(a, 0, sizeof(a)); memset(x, 0, sizeof(x)); for(int i=0; i<n; i++) { char s[30]; scanf("%s", s); for(int j=0; j<n; j++) if(s[j]=='y') a[i*n+j][n*n] = 0; else a[i*n+j][n*n] = 1; } equ=n*n; var=n*n; for(int i=0; i<var; i++) { a[i][i] = 1; if(i%n!=0) a[i-1][i] = 1; if(i%n!=n-1) a[i+1][i] = 1; if(i>n-1) a[i-n][i] = 1; if(i<(n-1)*n) a[i+n][i] = 1; } //debug(); int t = gauss(); if(t == -1) printf("inf\n"); else printf("%d\n", t); } return 0; }

浙公网安备 33010602011771号