Fliptile POJ 3279(反转)

原题

题目链接

题目分析

对于N行M列的矩阵,先看看左上角的点,能使该点翻转的有(1,1)、(1,2)和(2,1),无法确定该通过哪个点来翻转(1,1).不妨先确定好第一行的翻转情况,也就是说该不该翻(1,1)和(1,2)已经确定了,则此时只有(2,1)能翻转点(1,1),这时候就能直接判断了,因此可以确定第二行的翻转情况,同理迭代到最后一行,则整个矩阵的翻转情况都已确认完毕,此时只需要检验最后一行是否有黑色-1的即可.这里枚举第一行的翻转情况可用二进制枚举,则总的复杂度为O(N*M*2M).

代码

  1 #include <cstdio>
  2 #include <cstdlib>
  3 #include <iostream>
  4 #include <algorithm>
  5 #include <utility>
  6 #include <ctime>
  7 #include <cmath>
  8 #include <cstring>
  9 #include <string>
 10 #include <stack>
 11 #include <queue>
 12 #include <vector>
 13 #include <set>
 14 #include <map>
 15 
 16 using namespace std;
 17 typedef unsigned long long ULL;
 18 typedef long long LL;
 19 typedef long double LB;
 20 const int INF_INT=0x3f3f3f3f;
 21 const LL INF_LL=0x3f3f3f3f3f3f3f3f;
 22 
 23 int N,M;
 24 int grid[15][15];
 25 int f[15][15];
 26 
 27 bool check()
 28 {
 29     int t=N-1;
 30     int sum=f[t][0];
 31     for(int i=0;i<M;i++)
 32     {
 33         if(i-2>=0) sum-=f[t][i-2];
 34         if(t-1>=0)
 35         {
 36             sum+=f[t-1][i];
 37             if(i-1>=0) sum-=f[t-1][i-1];
 38         }
 39         if(i+1<M) sum+=f[t][i+1];
 40         if(sum&1)
 41         {
 42             if(!grid[t][i]) return false;
 43         }
 44         else
 45         {
 46             if(grid[t][i]) return false;
 47         }
 48     }
 49     return true;
 50 }
 51 
 52 int main()
 53 {
 54 //    freopen("testdata.in","r",stdin);
 55 //  freopen("std.out","w",stdout);
 56     cin>>N>>M;
 57     for(int i=0;i<N;i++)
 58         for(int j=0;j<M;j++)
 59             cin>>grid[i][j];
 60     bool s=false;
 61     for(int i=0;i<(1<<M);i++)
 62     {
 63         for(int j=0;j<M;j++)
 64             f[0][j]=(i>>j)&1;
 65 
 66         for(int j=0;j<N-1;j++)
 67         {
 68             int sum=f[j][0];
 69             for(int k=0;k<M;k++)
 70             {
 71                 if(k-2>=0) sum-=f[j][k-2];
 72                 if(j-1>=0)
 73                 {
 74                     sum+=f[j-1][k];
 75                     if(k-1>=0) sum-=f[j-1][k-1];
 76                 }
 77                 if(k+1<M) sum+=f[j][k+1];
 78                 if(sum&1)
 79                 {
 80                     if(grid[j][k]) f[j+1][k]=0;
 81                     else f[j+1][k]=1;
 82                 }
 83                 else
 84                 {
 85                     if(grid[j][k]) f[j+1][k]=1;
 86                     else f[j+1][k]=0;
 87                 }
 88             }
 89         }
 90         if(check())
 91         {
 92             s=true;
 93             break;
 94         }
 95     }
 96     if(s)
 97     {
 98         for(int i=0;i<N;i++)
 99         {
100             for(int j=0;j<M;j++)
101             {
102                 if(!j) printf("%d",f[i][j]);
103                 else printf(" %d",f[i][j]);
104             }
105             cout<<endl;
106         }
107     }
108     else printf("IMPOSSIBLE\n");
109     return 0;
110 }

 

posted @ 2019-10-27 14:07  VBL  阅读(137)  评论(0编辑  收藏  举报