通过二进制异或来模拟翻转的过程
刚开始自己没想到借鉴了大佬的做法
https://www.cnblogs.com/agenthtb/p/6033081.html
大佬原文
但是我认为字典序emmm好像应该是用pre
另外自己理解了以后还是有几个地方写的有问题以后要注意
#include<stdio.h>
#include<string.h>
#define inf 0x3f3f3f
int filp[17][17],pre[17][17],map[17][17],ans[17][17];
int n,m,temp;
int res=inf;
int calc(int s)
{
for(int i=0;i<m;i++)//i是从0开始的,另外这里的i是做指数的所以是用m为界限
{
if(s&(1<<i)){
pre[0][i]=1;
filp[0][i]^=1;
if(i-1>=0) filp[0][i-1]^=1;
if(i+1<m) filp[0][i+1]^=1;
if(1<n) filp[1][i]^=1;
}
}
for(int i=1;i<n;i++)
for(int j=0;j<m;j++)
{
if(filp[i-1][j]==1){
pre[i][j]=1;
filp[i-1][j]^=1;
filp[i][j]^=1;
if(j-1>=0)filp[i][j-1]^=1;
if(j+1<m) filp[i][j+1]^=1;
if(i+1<n) filp[i+1][j]^=1;
}
}
for(int i=0;i<m;i++)
if(filp[n-1][i]) return inf;
int res=0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
if(pre[i][j]) res++;
return res;
}
int main()
{
while(scanf("%d%d",&n,&m)!=EOF){//这里是反的。强行换成n行m列
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
scanf("%d",&map[i][j]);
memset(ans,0,sizeof(ans));
int res=inf;
for(int i=0;i<(1<<m);i++)
{
memcpy(filp,map,sizeof(map));
memset(pre,0,sizeof(pre));
temp=calc(i);//这个真的是2的n次方之内所有的数都要试验、、不是2
的次方才试验
if(temp<res) {
res=temp;
memcpy(ans,pre,sizeof(pre));
}
}
if(res==inf)
printf("IMPOSSIBLE\n");
else{
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
printf("%d ",ans[i][j]);
printf("\n");
}
}
}
return 0;
}