参考博客
二进制枚举第一行有一个好处就是它本身就是按照字典序大小枚举的
#include <cstdio>
#include <queue>
#include <string.h>
#include <iostream>
using namespace std;
int n,m,f;
int mp[23][23];
int mp2[23][23];
int turn[23][23];
void inint(){
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
mp2[i][j]=mp[i][j];
}
}
}
void L(int x,int y){
turn[x][y]=1;mp2[x][y]^=1;
mp2[x-1][y]^=1;mp2[x+1][y]^=1;
mp2[x][y-1]^=1;mp2[x][y+1]^=1;
}
int main(){
cin >> n >> m;
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
cin >> mp[i][j];
}
}</iostream></queue></cstdio>

    for(int k=0;k<(1<<m);++k){  //m列,所以一共有2^m种情况(m位枚举二进制),又因为需要靠k来将turn数组初始化,所以从0开始(因为从1开始,会漏掉0..0..0这种情况,且要到达(1<<m)这种情况,要进位即m位表示不出这个数值的大小)
        inint();f=0;
        memset(turn,0,sizeof(turn));
        for(int j=1;j<=m;++j){
            if(k&(1<<(j-1))){   //1<<(j-1) 表示1向左移j-1位,表示第j位为1,其余位是0
                                           // k&(1<<(j-1)) 表示k的第j位是否为1
                turn[1][j]=1,L(1,j);   //若i的j位为1,就令数组的j位为1  //turn数组的第一行记录二进制枚举的情况
            } 
        }
        for(int i=2;i<=n;++i){
            for(int j=1;j<=m;++j){
                if(mp2[i-1][j]) L(i,j);
            }
        }

//
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
if(mp2[i][j]){
f=1;break;
}
}
if(f) break;
}
if(f) continue;
else{
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
cout << turn[i][j] << " ";
}
cout << endl;
}
return 0;
}
}
cout << "IMPOSSIBLE" << endl;
return 0;
}