POJ 3279 搜索

来源:互联网 发布:骇战网络暴力 编辑:程序博客网 时间:2024/05/16 14:02

给出最高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;}


0 0