poj 3279

暴力枚举第一行,然后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\n");

        else

        {

            for(int i=1;i<=n;i++)

            {

                for(int j=1;j<=m;j++)

                printf("%d ",answer[i][j]);

                printf("\n");

            }

        }

    }

    return 0;

}


 

 

你可能感兴趣的:(poj)