POJ 3279 Fliptile(反转)

Description
一个m*n的格子,每个格子可以反转正反面,一面黑一面白,农夫约翰的牛现在玩游戏,把所有格子都反转成白色,因牛蹄很大,每次反转一个格子会让其上下左右相邻接的格子也反转。现在给定格子颜色,求最少操作次数完成该游戏,如果不能完成则输出IMPOSSIBLE
Input
第一行两个整数m和n表示格子的行列数,之后一个m*n矩阵表示格子颜色,0表示白色,1表示黑色
Output
如能完成游戏则输出最少步数,如果不能则输出IMPOSSIBLE
Sample Input
4 4
1 0 0 1
0 1 1 0
0 1 1 0
1 0 0 1
Sample Output
0 0 0 0
1 0 0 1
1 0 0 1
0 0 0 0
Solution
因为最后格子状态只能为全黑或全白,以将格子变成全黑为例,首先枚举第一行的反转情况,然后一行行向下递推,后面格子的反转必须使得前一行格子变成黑色,这样一来当将第四行反转完后前三行都为黑色,这时只需判断第四行是否全黑即可,对于每次满足条件的枚举枚举更新最小反转次数
Code

#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
using namespace std;
#define maxn 16
const int dx[5]={-1,0,0,0,1};//邻接格子坐标 
const int dy[5]={0,-1,0,1,0};
int m,n;
int map[maxn][maxn];//格子初始状态 
int ans[maxn][maxn];//保存最优解 
int temp[maxn][maxn];//保存中间结果 
int get(int x,int y)//查询(x,y)的颜色 
{
    int c=map[x][y];
    for(int i=0;i<5;i++)
    {
        int xx=x+dx[i],yy=y+dy[i];
        if(xx>=0&&xx<m&&yy>=0&&yy<n)
            c+=temp[xx][yy];
    }
    return c%2;
}
int solve()//求出第一行确定情况下的最少操作次数,不存在返回-1 
{
    for(int i=1;i<m;i++)
        for(int j=0;j<n;j++)
            if(get(i-1,j)!=0)//(i-1,j)是黑色,则必须反转此格子 
                temp[i][j]=1;
    for(int j=0;j<n;j++)//判断最后一行是否为全白 
        if(get(m-1,j)!=0)//无解 
            return -1;
    int res=0;
    for(int i=0;i<m;i++)//统计反转次数 
        for(int j=0;j<n;j++)
            res+=temp[i][j];
    return res;
}
int main()
{
    scanf("%d%d",&m,&n);
    for(int i=0;i<m;i++)
        for(int j=0;j<n;j++)
            scanf("%d",&map[i][j]);
    int res=-1;
    for(int i=0;i<1<<n;i++)//按照字典序尝试第一行所有可能性 
    {
        memset(temp,0,sizeof(temp));//初始化 
        for(int j=0;j<n;j++)
            temp[0][n-1-j]=i>>j&1;
        int num=solve();
        if(num>=0&&(res<0||res>num))
        {
            res=num;//更新最少操作次数 
            memcpy(ans,temp,sizeof(temp));//复制最优解 
        }
    }
    if(res<0)//无解 
        printf("IMPOSSIBLE\n");
    else
        for(int i=0;i<m;i++)
            for(int j=0;j<n;j++)
                printf("%d%c",ans[i][j],j==n-1?'\n':' ');
    return 0;
}

你可能感兴趣的:(POJ 3279 Fliptile(反转))