题目链接: http://poj.org/problem?id=1681
题意: 有一个包含 n * n 个方格的正方形, w 表示其所在位置为白色, y 表示其所在位置为黄色. 对 (i, j) 位置进行一次操作则 (i, j), (i + 1, j), (i - 1, j), (i, j - 1), (i, j + 1) 位置的颜色变为原来的相反状态, 输出让所有方格都变成白色所需的最少操作步数, 若不能使所有方格都变成白色,则输出 inf .
思路: 这题和 poj 1222 (题解: http://www.cnblogs.com/geloutingyu/p/7565405.html) 类似, 同样也可以枚举第一行的所有操作, 或者解 mod2 方程组.
解法1:
注意要求出所有解法然后取操作数最小值.
1 #include <iostream> 2 #include <stdio.h> 3 #include <string.h> 4 using namespace std; 5 6 const int inf = 1e9; 7 const int MAXN = 1e2; 8 int mp[MAXN][MAXN], sol[MAXN][MAXN]; 9 int n, ans = inf; 10 11 int check(void){ 12 int gel[MAXN][MAXN], cnt = 0; 13 memcpy(gel, mp, sizeof(mp)); 14 for(int i = 1; i <= n; i++){ 15 if(sol[1][i]){ 16 cnt++; 17 gel[1][i] ^= 1; 18 gel[1][i - 1] ^= 1; 19 gel[1][i + 1] ^= 1; 20 gel[2][i] ^= 1; 21 gel[0][i] ^= 1; 22 } 23 } 24 for(int i = 2; i <= n; i++){ 25 for(int j = 1; j <= n; j++){ 26 if(gel[i - 1][j]){ 27 cnt++; 28 sol[i][j] = 1; 29 gel[i][j] ^= 1; 30 gel[i][j - 1] ^= 1; 31 gel[i][j + 1] ^= 1; 32 gel[i - 1][j] ^= 1; 33 gel[i + 1][j] ^= 1; 34 }else sol[i][j] = 0; 35 } 36 } 37 for(int i = 1; i <= n; i++){ 38 if(gel[n][i]) return inf; 39 } 40 return cnt; 41 } 42 43 void dfs(int m){ 44 if(m > n){ 45 ans = min(ans, check()); 46 return; 47 } 48 sol[1][m] = 1; 49 dfs(m + 1); 50 sol[1][m] = 0; 51 dfs(m + 1); 52 } 53 54 int main(void){ 55 int t; 56 string s; 57 cin >> t; 58 while(t--){ 59 cin >> n; 60 for(int i = 1; i <= n; i++){ 61 cin >> s; 62 for(int j = 0; j < s.size(); j++){ 63 if(s[j] == 'w') mp[i][j + 1] = 1; 64 else mp[i][j + 1] = 0; 65 } 66 } 67 ans = inf; 68 dfs(1); 69 if(ans == inf) cout << "inf" << endl; 70 else cout << ans << endl; 71 } 72 return 0; 73 }