暴力枚举第一行,然后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 "); else { for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) printf("%d ",answer[i][j]); printf(" "); } } } return 0; }