给出最高15*15的0 1矩阵,每次可以翻转一个点,其相邻的4个点都被翻转,问最少翻转几次可以全部变为0
题中要求的字典序根本不用考虑。。。
枚举第一行的翻转所有翻转情况然后逐行向下更新即可,因为第一行确定后,后面的都有唯一解
#include "stdio.h" #include "string.h" int n,m; int vis[21][21],b[21][21],a[21][21],pri[21][21]; void on(int x,int y) { b[x][y]^=1; if (x-1>=0) b[x-1][y]^=1; if (y-1>=0) b[x][y-1]^=1; b[x+1][y]^=1; b[x][y+1]^=1; } int main() { int ok,ans,sum,cnt,i,j,w,key,flag; while (scanf("%d%d",&n,&m)!=EOF) { for (i=0;i<n;i++) for (j=0;j<m;j++) scanf("%d",&a[i][j]); cnt=(1<<m)-1; ans=0x7fffffff; ok=0; for (w=0;w<=cnt;w++) { memset(vis,0,sizeof(vis)); memcpy(b,a,sizeof(a)); sum=0; for (i=0;i<m;i++) { key=w&(1<<i); if (key!=0) { sum++; on(0,i); vis[0][i]=1; } } for (i=1;i<n;i++) { if (sum>=ans) break; for (j=0;j<m;j++) if (b[i-1][j]==1) { on(i,j); vis[i][j]=1; sum++; if (sum>=ans) break; } } if (sum>=ans || i!=n) continue; flag=1; for (j=0;j<m;j++) if (b[n-1][j]==1) {flag=0; break;} if (flag==1 && sum<ans) { ok=1; ans=sum; memcpy(pri,vis,sizeof(vis)); } } if (ok==0) printf("IMPOSSIBLE\n"); else { for (i=0;i<n;i++) { printf("%d",pri[i][0]); for (j=1;j<m;j++) printf(" %d",pri[i][j]); printf("\n"); } } } return 0; }
时间: 2024-11-08 21:49:28