状态压缩+枚举 POJ 3279 Fliptile

 

题目传送门

 1 /*
 2     题意:问最少翻转几次使得棋子都变白,输出翻转的位置
 3     状态压缩+枚举:和之前UVA_11464差不多,枚举第一行,可以从上一行的状态知道当前是否必须翻转
 4 */
 5 #include <cstdio>
 6 #include <cstring>
 7 #include <algorithm>
 8 using namespace std;
 9 
10 const int MAXN = 20;
11 const int INF = 0x3f3f3f3f;
12 int a[MAXN][MAXN];
13 int b[MAXN][MAXN];
14 int ans[MAXN][MAXN];
15 int dx[5] = {-1, 0, 0, 0, 1};
16 int dy[5] = {0, 1, 0, -1, 0};
17 int n, m;
18 
19 int get_col(int x, int y)   {
20     int ret = a[x][y];
21     for (int i=0; i<5; ++i) {
22         int tx = x + dx[i], ty = y + dy[i];
23         if (tx < 0 || tx >= n || ty < 0 || ty >= m) continue;
24         ret += b[tx][ty];
25     }
26     return ret & 1;
27 }
28 
29 int check(int s)    {
30     memset (b, 0, sizeof (b));
31     for (int i=0; i<m; ++i) {
32         if (s & (1 << i))   b[0][i] = 1;
33     }
34     for (int i=1; i<n; ++i) {
35         for (int j=0; j<m; ++j) {
36             if (get_col (i-1, j))   b[i][j] = 1;
37         }
38     }
39     for (int i=0; i<m; ++i) if (get_col (n-1, i))   return INF;
40     int ret = 0;
41     for (int i=0; i<n; ++i) {
42         for (int j=0; j<m; ++j) ret += b[i][j];
43     }
44     return ret;
45 }
46 
47 int main(void)  {       //POJ 3279 Fliptile
48     while (scanf ("%d%d", &n, &m) == 2) {
49         for (int i=0; i<n; ++i)    {
50             for (int j=0; j<m; ++j)    {
51                 scanf ("%d", &a[i][j]);
52             }
53         }
54         int mn = INF;
55         memset (ans, 0, sizeof (ans));
56         for (int i=0; i<(1<<m); ++i)    {
57             int res = check (i);
58             if (res < mn)   {
59                 mn = res;
60                 for (int i=0; i<n; ++i)    {
61                     for (int j=0; j<m; ++j)    {
62                         if (b[i][j])    ans[i][j] = 1;
63                         else    ans[i][j] = 0;
64                     }
65                 }
66             }
67         }
68         if (mn < INF)   {
69             for (int i=0; i<n; ++i)    {
70                 for (int j=0; j<m; ++j)    printf ("%d%c", ans[i][j], (j == m-1) ? '\n' : ' ');
71             }
72         }
73         else    puts ("IMPOSSIBLE");
74     }
75 
76     return 0;
77 }

 

posted @ 2015-08-02 13:24  Running_Time  阅读(287)  评论(0编辑  收藏  举报