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 }