二维翻转问题,比较复杂,琢磨了好久。
这个问题比一维的要麻烦好多,一维裸暴力就能过去。目测这题的数据量裸暴力也能过,但是我还是作死的选择了搜索。。。
搜索上没有难度,需要注意的问题是对翻转点的标记以及状态转移(是这么叫的吗?。。。)
这一周以来最大的工程,代码摆上,欢迎hack
PS:诸如“这种破代码居然还要写这么久哼哼简直就是渣渣。。。”的话就不要说了,我知道我知道= =
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define INF 1000000010
using namespace std;
int dx[5][2] = {{0, 1}, {1, 0}, {0, 0}, {-1, 0}, {0, -1}};
int n, m;
int a[20][20], cz[20][20], ans[20][20];
int judge(int x, int y)
{
int res = a[x][y];
for(int i = 0; i < 5; i++){
int xx = dx[i][0] + x;
int yy = dx[i][1] + y;
if(xx >= 0 && xx < n && yy >= 0 && yy < m)
res += cz[xx][yy];
}
return res % 2;
}
int main()
{
//freopen("in.txt", "r", stdin);
while(~scanf("%d%d", &n, &m)){
int ret = INF;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++)
scanf("%d", &a[i][j]);
for(int i = 0; i < (1 << m); i++){ //二进制
memset(cz, 0 ,sizeof(cz));
int res = 0;
for(int j = 0; j < m; j++){
cz[0][m - j - 1] = (i >> j) & 1;
res += cz[0][m - j - 1];
}
for(int j = 1; j < n; j++)
for(int k = 0; k < m; k++)
if(judge(j - 1, k)){
cz[j][k] = 1;
res++;
}
bool flag = true;
for(int j = 0; j < m; j++)
if(judge(n - 1, j)){
flag = false;
break;
}
if(flag && res < ret){
ret = res;
memcpy(ans, cz, sizeof(cz));
}
}
if(ret == INF) printf("IMPOSSIBLE\n");
else{
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++)
printf("%d ", cz[i][j]);
printf("\n");
}
}
}
return 0;
}