Painter's Problem
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 5352 | Accepted: 2588 |
Description
There is a square wall which is made of n*n small square bricks. Some bricks are white while some bricks are yellow. Bob is a painter and he wants to paint all the bricks yellow. But there is something wrong with Bob's brush. Once he uses this brush to paint brick (i, j), the bricks at (i, j), (i-1, j), (i+1, j), (i, j-1) and (i, j+1) all change their color. Your task is to find the minimum number of bricks Bob should paint in order to make all the bricks yellow.
Input
The first line contains a single integer t (1 <= t <= 20) that indicates the number of test cases. Then follow the t cases. Each test case begins with a line contains an integer n (1 <= n <= 15), representing the size of wall. The next n lines represent the
original wall. Each line contains n characters. The j-th character of the i-th line figures out the color of brick at position (i, j). We use a 'w' to express a white brick while a 'y' to express a yellow brick.
Output
For each case, output a line contains the minimum number of bricks Bob should paint. If Bob can't paint all the bricks yellow, print 'inf'.
Sample Input
2
3
yyy
yyy
yyy
5
wwwww
wwwww
wwwww
wwwww
wwwww
Sample Output
0
15
题意:
一个n*n 的木板,每个格子都可以染成白色和黄色,一旦我们对某个格子染色,其上下左右都将改变颜色
求将所有的格子染成黄色最少需要几次,若不能则输出inf。
当有多个自由变元时,需要进行枚举求出最小值
1 /* 2 poj1681 3 类似于一元开关问题。把二维矩阵转换成一维矩阵来看。 4 在求出答案之后,对于有很多解的考虑枚举自由变元来求解 5 最小值 6 */ 7 #include <iostream> 8 #include <cstdio> 9 #include <cstdlib> 10 #include <cstring> 11 #include <algorithm> 12 #include <cmath> 13 using namespace std; 14 typedef long long ll; 15 typedef long double ld; 16 17 using namespace std; 18 const int maxn = 300; 19 20 int equ,var; 21 int a[maxn][maxn]; 22 int x[maxn]; 23 int free_x[maxn]; 24 int free_num; 25 26 int Gauss() 27 { 28 int max_r,col,k; 29 free_num = 0; 30 for(k = 0,col = 0; k < equ && col < var; k++,col++) 31 { 32 max_r = k; 33 for(int i = k+1; i < equ; i++) 34 { 35 if(abs(a[i][col]) > abs(a[max_r][col])) 36 max_r = i; 37 } 38 if(a[max_r][col] == 0) 39 { 40 k --; 41 free_x[free_num++] = col; 42 continue; 43 } 44 if(max_r != k) 45 { 46 for(int j = col; j < var+1; j++) 47 swap(a[k][j],a[max_r][j]); 48 49 } 50 for(int i = k + 1; i < equ; i++) 51 { 52 if(a[i][col] != 0) 53 { 54 for(int j = col; j < var+1; j++) 55 a[i][j] ^= a[k][j]; 56 } 57 } 58 59 } 60 for(int i = k; i < equ; i++) 61 if(a[i][col] != 0) 62 return -1; 63 if(k < var) return var-k; 64 65 for(int i = var-1; i >= 0; i--) 66 { 67 x[i] = a[i][var]; 68 for(int j = i +1; j < var; j++) 69 x[i] ^= (a[i][j] && x[j]); 70 71 } 72 return 0; 73 74 } 75 76 int n; 77 void ini() 78 { 79 memset(a,0,sizeof(a)); 80 memset(x,0,sizeof(x)); 81 equ = n*n; 82 var = n*n; 83 for(int i = 0;i < n;i++) 84 { 85 for(int j = 0;j < n;j++) 86 { 87 int tt = i*n+ j; 88 a[tt][tt] =1; 89 if(i > 0) a[(i-1)*n+j][tt] = 1; 90 if(i < n-1) a[(i+1)*n+j][tt] = 1; 91 if(j > 0) a[tt-1][tt] = 1; 92 if(j < n-1) a[tt+1][tt] =1; 93 } 94 } 95 } 96 97 char str[30][30]; 98 /* 99 2 100 3 101 yyy 102 yyy 103 yyy 104 5 105 wwwww 106 wwwww 107 wwwww 108 wwwww 109 wwwww 110 */ 111 int main() 112 { 113 int T; 114 char color; 115 scanf("%d",&T); 116 while(T--) 117 { 118 scanf("%d",&n); 119 ini(); 120 for(int i = 0; i < n; i++) 121 { 122 scanf("%s",str[i]); 123 for(int j = 0; j < n; j++) 124 { 125 if(str[i][j] == 'y') 126 a[i*n+j][n*n] = 0; 127 else 128 a[i*n+j][n*n] = 1; 129 } 130 } 131 int t = Gauss(); 132 if(t == -1) 133 { 134 printf("inf "); 135 } 136 else if(t == 0) 137 { 138 int ans = 0; 139 for(int i = 0; i < n*n; i++) 140 ans += x[i]; 141 printf("%d ",ans); 142 } 143 else 144 { 145 int ans = 0x3f3f3f3f; 146 int tot = (1 << t); 147 for(int i = 0; i < tot; i++) 148 { 149 int cnt = 0; 150 for(int j = 0; j < t; j++) 151 { 152 if(i & (1 << j)) 153 { 154 cnt ++; 155 x[free_x[j]]= 1; 156 } 157 else x[free_x[j]]= 0; 158 } 159 160 for(int j = var-t-1; j >= 0; j--) 161 { 162 int dex; 163 for(dex = j; dex < var; dex++) 164 if(a[j][dex]) 165 break; 166 x[dex] = a[j][var]; 167 for(int l = dex +1; l <var ; l++) 168 { 169 if(a[j][l]) 170 x[dex] ^= x[l]; 171 } 172 cnt += x[dex]; 173 } 174 ans = min(ans,cnt); 175 } 176 printf("%d ",ans); 177 } 178 } 179 return 0; 180 }