标签:
给出最高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;
}
标签:
原文地址:http://blog.csdn.net/u011932355/article/details/44172163