D - Fliptile

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <math.h>
 4 #include <algorithm>
 5 #include <queue>
 6 #include <string.h>
 7 using namespace std;
 8 
 9 const int INF = 0xfffffff;
10 int g[17][17];
11 int f[17][17] = {};
12 int ans[17][17] = {};
13 int mmin = INF;
14 
15 bool judge(int n,int m)//判断最后一行是否全为0
16 {
17     for(int i=1;i<=m;i++)
18     {
19         int t = f[n][i]+f[n][i-1]+f[n][i+1]+f[n-1][i];
20         if( (g[n][i]+t)&1 )
21             return false;
22         }
23     return true;
24 }
25 
26 void dfs(int n,int m,int k,int num)
27 {
28     if(num > mmin)//剪枝
29         return;
30     if(k > n)
31     {
32         if(judge(n, m) && mmin>num)//判断是否符合条件
33         {
34             memcpy(ans, f, sizeof(f));
35             mmin = num;
36         }
37         return;
38     }
39     int t = 0;
40     for(int i=1;i<=m;i++)
41     {
42         if((g[k-1][i]+f[k-2][i]+f[k-1][i-1]+f[k-1][i+1]+f[k-1][i])&1)//上一行是否为1,即是否需要翻转
43         {
44             f[k][i] = 1;
45             t++;
46         }
47         else
48             f[k][i] = 0;
49     }
50     dfs(n, m, k+1, num+t);
51 }
52 
53 //n,m行列数   k当前列  num第一行翻转的次数
54 void todfs(int n, int m, int k, int num)
55 {
56     if(k > m)
57     {
58         dfs(n, m, 2, num); //对第一行每种情况进行搜索
59         return;
60     }
61     f[1][k] = 0;      //不翻转
62     todfs(n, m, k+1, num);
63     f[1][k] = 1;      //翻转,num+1
64     todfs(n, m, k+1, num+1);
65 }
66 
67 int main()
68 {
69     int n,m;
70     cin >> n >> m;
71     for(int i=1;i<=n;i++)
72         for(int j=1;j<=m;j++)
73             cin>>g[i][j];
74     todfs(n, m, 1, 0);     //递归遍历第一行所有情况
75     if(mmin == INF)
76         cout<<"IMPOSSIBLE"<<endl;
77     else
78         for(int i=1;i<=n;i++)
79         {
80             for(int j=1;j<=m;j++)
81                 cout<<ans[i][j]<<" ";
82             cout<<endl;
83         }
84     return 0;
85 }

 

posted @ 2018-04-29 21:53  ouyang_wsgwz  阅读(141)  评论(0编辑  收藏  举报