Poj--1753(数学,高斯消元 + 枚举 or 暴力乱搞)
2014-09-18 00:25:47
思路:这题可以用二进制状态压缩来DFS暴力搞,由于最近在学高斯消元,就用用了。由于这题要求最小步骤,所以在有自由变元时要枚举自由变元,其他的与1222差不多。
借鉴了kuangbin的博客。敲完这题,对高斯消元、自由变元又有了更深的理解。
1 /************************************************************************* 2 > File Name: 1753.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Wed 17 Sep 2014 09:41:16 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <queue> 14 #include <iostream> 15 #include <algorithm> 16 using namespace std; 17 typedef long long ll; 18 const int INF = 1 << 29; 19 typedef int Matrix[20][20]; 20 21 char g[10][10]; 22 Matrix A; 23 24 void Init(){ 25 memset(A,0,sizeof(A)); 26 for(int i = 0; i < 16; ++i){ 27 A[i][i] = 1; 28 if(i >= 4) A[i][i - 4] = 1; //up 29 if(i + 4 < 16) A[i][i + 4] = 1; //down 30 if(i % 4 != 0) A[i][i - 1] = 1; //left 31 if((i + 1) % 4 != 0) A[i][i + 1] = 1; //right 32 } 33 } 34 35 int Gauss(){ 36 int pfx[20],x[20],num = 0; 37 for(int i = 0; i < 20; ++i) pfx[i] = x[i] = 0; 38 int equ,var; equ = var = 16; 39 int i,j,k,r,col = 0; 40 for(i = 0; i < equ && col < var; ++i,++col){ 41 r = i; 42 for(j = i + 1; j < equ; ++j) if(A[j][col]){ 43 r = j; 44 break; 45 } 46 if(r != i) 47 for(j = col; j <= var; ++j) swap(A[i][j],A[r][j]); 48 if(A[i][col] == 0){ 49 --i; 50 pfx[num++] = col; 51 continue; 52 } 53 for(k = i + 1; k < equ; ++k) 54 if(A[k][col]){ 55 for(j = 0; j <= var; ++j) A[k][j] ^= A[i][j]; 56 } 57 //Debug(); 58 } 59 for(k = i; k < equ; ++k) 60 if(A[k][col] != 0) 61 return -1; 62 int ra = 1 << num,res = INF; 63 for(k = 0; k < ra; ++k){ 64 int cnt = 0,pos = k; 65 for(j = 0; j < num; ++j){ 66 x[pfx[j]] = (pos & 1); 67 if(x[pfx[j]]) ++cnt; 68 pos >>= 1; 69 } 70 for(j = i - 1; j >= 0; --j){ 71 int tmp = A[j][var]; 72 for(int q = j + 1; q < var; ++q) 73 if(A[j][q]) tmp ^= x[q]; 74 x[j] = tmp; 75 if(x[j]) ++cnt; 76 } 77 if(cnt < res) res = cnt; 78 } 79 return res; 80 } 81 82 int main(){ 83 int ans = INF; 84 for(int i = 0; i < 4; ++i) scanf("%s",g[i]); 85 // first 86 Init(); 87 for(int i = 0; i < 4; ++i) 88 for(int j = 0; j < 4; ++j) if(g[i][j] == 'b'){ 89 A[i*4 + j][16] = 1; 90 } 91 int t = Gauss(); 92 if(t != -1) ans = min(ans,t); 93 //second 94 Init(); 95 for(int i = 0; i < 4; ++i) 96 for(int j = 0; j < 4; ++j) if(g[i][j] == 'w'){ 97 A[i*4 + j][16] = 1; 98 } 99 t = Gauss(); 100 if(t != -1) ans = min(ans,t); 101 if(ans != INF) 102 printf("%d\n",ans); 103 else 104 printf("Impossible\n"); 105 return 0; 106 }