POJ 3279 Fliptile

爆搜。

一个一个位置搜下去。第一列的格子可以反转也可以不反转,之后的每一列,看他左边的那一个格是1还是0,如果是1,这一格必须反转,否则必须不反转。这是一个很强的剪枝。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;

const int maxn=20;
int n,m;
int a[maxn][maxn];
int flag[maxn][maxn];
int ans[maxn][maxn];
int cnt,sum;
int dir[4][2]=
{
    {1,0},
    {-1,0},
    {0,1},
    {0,-1},
};

void c()
{
    for(int i=0; i<n; i++)
        for(int j=0; j<m; j++)
            ans[i][j]=flag[i][j];
}

bool P(int a,int b)
{
    if(a>=0&&a<n&&b>=0&&b<m) return 1;
    return 0;
}

void dfs(int id,int tot,int re)
{
    int tmp=re;

    if(tot>=cnt) return;

    if(re==0)
    {
        c();
        cnt=min(cnt,tot);
        return ;
    }

    if(id==n*m) return;

    int x=id%n,y=id/n;

    if(y==0||a[x][y-1]==1)
    {
        flag[x][y]=1;
        a[x][y]=(a[x][y]^1);
        if(a[x][y]==1) tmp++;
        else tmp--;
        for(int i=0; i<4; i++)
        {
            int nx=x+dir[i][0],ny=y+dir[i][1];
            if(P(nx,ny))
            {
                a[nx][ny]=(a[nx][ny]^1);
                if(a[nx][ny]==1) tmp++;
                else tmp--;
            }
        }
        dfs(id+1,tot+1,tmp);
        flag[x][y]=0;
        a[x][y]=(a[x][y]^1);
        for(int i=0; i<4; i++)
        {
            int nx=x+dir[i][0],ny=y+dir[i][1];
            if(P(nx,ny)) a[nx][ny]=(a[nx][ny]^1);
        }
    }
    if(y==0||a[x][y-1]==0)
        dfs(id+1,tot,re);
}

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        sum=0;
        for(int i=0; i<n; i++)
            for(int j=0; j<m; j++)
            {
                scanf("%d",&a[i][j]);
                if(a[i][j]==1) sum++;
            }

        cnt=0x7fffffff;
        dfs(0,0,sum);
        if(cnt==0x7fffffff) printf("IMPOSSIBLE\n");
        else
        {
            for(int i=0; i<n; i++)
            {
                for(int j=0; j<m; j++)
                {
                    printf("%d",ans[i][j]);
                    if(j<m-1) printf(" ");
                    else printf("\n");
                }
            }
        }
    }
    return 0;
}

 

posted @ 2016-04-15 15:03  Fighting_Heart  阅读(192)  评论(0编辑  收藏  举报