暴力枚举第一行,然后n*m得出答案。至于字典序的问题,只要按照字典序来枚举就好了。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn=15+2;
int n,m;
int a[maxn][maxn];
bool fla[maxn][maxn],ans[maxn][maxn],answer[maxn][maxn];
int mcost;
void work()
{
int ret=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
fla[i][j]=a[i][j];
for(int i=1;i<=m;i++)
if(ans[1][i])
{
ret++;
fla[1][i]=!fla[1][i];
fla[1][i+1]=!fla[1][i+1];
fla[1][i-1]=!fla[1][i-1];
fla[2][i]=!fla[2][i];
}
for(int i=1;i<n;i++)
for(int j=1;j<=m;j++)
if(fla[i][j]!=0)
{
ret++;
ans[i+1][j]=1;
for(int p=-1;p<=1;p++)
for(int q=-1;q<=1;q++)
if((fabs(p)+fabs(q))<=1)
fla[i+1+p][j+q]=!fla[i+1+p][j+q];
}
else
ans[i+1][j]=0;
for(int i=1;i<=m;i++)
if(fla[n][i]) return ;
if(mcost>ret)
{
mcost=ret;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
answer[i][j]=ans[i][j];
}
}
void dfs(int t)
{
if(t==m+1)
{
work();
return ;
}
ans[1][t]=0;
dfs(t+1);
ans[1][t]=1;
dfs(t+1);
}
int main()
{
while(scanf("%d %d",&n,&m)!=EOF)
{
mcost=111111;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
}
dfs(1);
if(mcost>=111111)
printf("IMPOSSIBLE\n");
else
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
printf("%d ",answer[i][j]);
printf("\n");
}
}
}
return 0;
}