1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
| int T,M,N,K,I,a,b,c,cnt;
int di[] = {0,-1, 0, 1, 0}; // to move
int dj[] = {0, 0, 1, 0,-1};
bool arr[20][20], flip[20][20], tmp_flip;
pii ans; // {times, flip of first row}
void init(){
N = getint(), M = getint();
for(int i=0;i<N;i++)for(int j=0;j<M;j++)
arr[i][j] = getint(); // need to be reversed
}
inline bool ok(int &i, int &j){
return not(i<0 or j<0 or i>=N or j>=M);
}
inline bool need(int i, int j){
int ii,jj;
tmp_flip = 0;
for(int k=0;k<5;k++)
if(ok(ii=i+di[k], jj=j+dj[k]))
tmp_flip ^= flip[ii][jj];
return tmp_flip^arr[i][j];
}
int cal(){
int times = 0; // 注意,此時第0列已經flip,未記錄
for(int i=0;i+1<N;i++)
for(int j=0;j<M;j++)
if(need(i,j)) flip[i+1][j]=1, ++times;
for(int i=0;i<M;i++){
times += flip[0][i]; // 補紀錄第0列
if(need(N-1, i)) return -1;
}
return times;
}
// 只要翻好第一排,就唯一決定了全部的翻法
void sol(){
ans = MP(INT_MAX, 1);
for(int i=0;i<1<<M;i++){ // enumerate all status of flip
memset(flip, 0, sizeof(flip));
for(int j=0;j<M;j++)if((i>>j)&1)
flip[0][j] = 1;
a = cal();
if(a > -1 and a < ans.X) ans = MP(a, i);
}
if(ans.X == INT_MAX) puts("IMPOSSIBLE");
else {
memset(flip, 0, sizeof(flip));
for(int j=0;j<M;j++)if((ans.Y>>j)&1)
flip[0][j] = 1;
cal();
for(int i=0;i<N;i++)for(int j=0;j<M;j++)
cout << flip[i][j] << " \n"[j==M-1];
}
}
int main(){
init();
sol();
} |