POJ 3279 Fliptile 状态压缩,思路 难度:2

http://poj.org/problem?id=3279

明显,每一位上只需要是0或者1,

遍历第一行的所有取值可能,(1<<15,时间足够)对每种取值可能:

对于第0-n-2行,因为上一行和本身行都已确定,所以可以确定下一行

最后检查第n-1行是否满足条件即可

#include <cstdio>

#include <cstring>

#include <algorithm>

#include <queue>

using namespace std;

int maz[15][15];

int op[15][15];

int ans[15][15],mn;

int n,m;

void getop(int sta){

        memset(op,0,sizeof(op));

        for(int i=0;i<n;i++){

                if(sta&(1<<i)){

                        op[0][i]=1;

                }

        }

}

int getone(){

        int num=0;

        for(int i=0;i<n;i++){

                for(int j=0;j<m;j++){

                        num+=op[i][j];

                }

        }

        return num;

}

const int dx[4]={0,-1,0,0};

const int dy[4]={0,0,1,-1};

bool in(int x,int y){

        return x>=0&&x<n&&y>=0&&y<m;

}

bool judge(int x,int y){

        int num=maz[x][y];

        for(int i=0;i<4;i++){

                int tx=x+dx[i],ty=y+dy[i];

                if(in(tx,ty))num+=op[tx][ty];

        }

        return (num&1)==0;

}

int main(){

        scanf("%d%d",&n,&m);

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

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

                        scanf("%d",maz[i]+j);

        int mn=0x7ffffff;

        for(int sta=0;sta<(1<<n);sta++){

                getop(sta);

                for(int i=0;i<n-1;i++){

                        for(int j=0;j<m;j++){

                                if(!judge(i,j)){

                                        op[i+1][j]=1;

                                }

                        }

                }

                bool fl=true;

                for(int j=0;j<m;j++){

                        if(!judge(n-1,j)){

                                fl=false;

                                break;

                        }

                }

                if(fl){

                        int num=getone();

                        if(num<mn){

                                for(int i=0;i<n;i++){

                                        copy(op[i],op[i]+m,ans[i]);

                                }

                                mn=num;

                        }

                }

        }

        if(mn<=n*m)

        for(int i=0;i<n;i++){

                for(int j=0;j<m;j++){

                        printf("%d%c",ans[i][j],j==m-1?'\n':' ');

                }

        }

        else puts("IMPOSSIBLE");



        return 0;

}

  

你可能感兴趣的:(poj)