poj3279 Fliptile

来源:互联网 发布:淘宝怎样好评返现 编辑:程序博客网 时间:2024/06/08 17:11
枚举第一行的翻转所有翻转情况然后逐行向下更新,如果上一行是1的话,那么下面一行肯定要翻转,因为只有下面一行能影响上面一行。

最后判断一下,最后一行是不是都是0,如果都是,则维护最小的翻转次数。

#include<iostream>#include<cstdio>#include<cstdlib>#include<algorithm>#include<cmath>#include<queue>#include<cstring>#include<vector>#include<map>#define INF 1<<30using namespace std;int m,n,res;int tmp[20][20],a[20][20],b[20][20],aa[20][20];int judge(){    int i;    for(i=0; i<n; i++)        if(b[m-1][i])            return 0;    return 1;}void filp(int x,int y){    int next[5][2]= {{0,0},{0,1},{0,-1},{-1,0},{1,0}};    int k,tx,ty;    tmp[x][y]=1;    for(k=0; k<5; k++)    {        tx=next[k][0]+x;        ty=next[k][1]+y;        if(tx<0||ty<0||tx>m-1||ty>n-1)            continue;        b[tx][ty]=!b[tx][ty];    }}void sove(int t){    memcpy(b,a,sizeof(a));    memset(tmp,0,sizeof(tmp));    int ans=0,i,j;    for(i=0; i<n; i++)        if((t>>i)&1)        {            filp(0,i);            ans++;        }    for(i=1; i<m; i++)        for(j=0; j<n; j++)            if(b[i-1][j])            {                filp(i,j);                ans++;            }    if(judge()&&ans<res)    {        memcpy(aa,tmp,sizeof(tmp));        res=ans;    }}int main(){    int i,j;    while(~scanf("%d%d",&m,&n))    {        memset(a,0,sizeof(a));        for(i=0; i<m; i++)            for(j=0; j<n; j++)                scanf("%d",&a[i][j]);        int k=1<<n;        res=INF;        for(i=0; i<=k; i++)            sove(i);        if(res==INF)            printf("IMPOSSIBLE\n");        else        {            for(i=0; i<m; i++)                for(j=0; j<n; j++)                    printf("%d%c",aa[i][j],j==n-1?'\n':' ');        }    }    return 0;}


0 0
原创粉丝点击