poj1681 高斯消元

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 }



原文地址:https://www.cnblogs.com/Przz/p/5409645.html