POJ3279 Fliptile 枚举+简单搜索

题意:一个矩阵,每个点1或0,然后每次翻一个点,它周围上下左右(包括自己)1-》0,0-》1,问最少翻几次可以矩阵全是0,忽略题目说的字典序

分析:枚举第一行所有的情况,然后下面几行也随之确定了,然后看哪种好就行,因为每行宽最多15 所有二进制枚举一下。

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#include<map>
#include<stdlib.h>
#include<string>
using namespace std;
typedef long long LL;
const int maxn=20;
const int INF=0x3f3f3f3f;
int o[maxn][maxn];
int now[maxn][maxn];
int temp[maxn][maxn];
int res[maxn][maxn];
int n,m,ans;
int dx[4]= {0,0,-1,1};
int dy[4]= {-1,1,0,0};
void change(int x,int y)
{
    now[x][y]=1-now[x][y];
    for(int i=0; i<4; ++i)
    {
        int p=x+dx[i];
        int q=y+dy[i];
        if(p<1||p>n||q<1||q>m)continue;
        now[p][q]=1-now[p][q];
    }
}
bool check(int x,int y)
{
    if(now[x-1][y])return true;
    return false;
}
void solve(int x)
{
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=m; ++j)
            now[i][j]=o[i][j];
    int a[maxn],cnt=0,c=0,flag=0;
    memset(temp,0,sizeof(temp));
    memset(a,0,sizeof(a));
    while(x)
    {
        a[++cnt]=x%2;
        x>>=1;
        if(a[cnt])++c;
    }
    for(int i=1; i<=m; ++i)
        if(a[i])change(1,i),temp[1][i]++;
    for(int i=2; i<=n; ++i)
        for(int j=1; j<=m; ++j)
            if(check(i,j))++c,change(i,j),temp[i][j]++;
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=m; ++j)
            if(now[i][j])flag=1;
    if(!flag&&c<ans)
    {
        ans=c;
        for(int i=1; i<=n; ++i)
            for(int j=1; j<=m; ++j)
                res[i][j]=temp[i][j];
    }

}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=1; i<=n; ++i)
            for(int j=1; j<=m; ++j)
                scanf("%d",&o[i][j]);
        ans=INF;
        int l=(1<<m);
        for(int i=0; i<l; ++i)
            solve(i);
        if(ans==INF)
        {
            printf("IMPOSSIBLE\n");
            continue;
        }
        else
        {
            for(int i=1; i<=n; ++i)
            {
                for(int j=1; j<m; ++j)
                    printf("%d ",res[i][j]);
                printf("%d\n",res[i][m]);
            }
        }
    }
    return 0;
}
View Code

 

你可能感兴趣的:(POJ3279 Fliptile 枚举+简单搜索)