D

题目大意
翻瓷砖(姑且认为题目就是这个意思吧)
    农民约翰知道越聪明越快乐的牛产的牛奶越多(神马鬼理论),于是他开始安排牛进行一个智力运动在一个M*N (1 ≤ M ≤ 15; 1 ≤ N ≤ 15) 的网格中,每个网格都有一个正方形的瓷砖组成,当然每块瓷砖都是由黑色和白色两种颜色组成的。
    这个游戏是吧所有的瓷砖都变成白色??,奶牛在翻转瓷砖的时候会把四周的瓷砖一同翻转过来的,当然奶牛想用最少的步骤来翻转,如果有多种翻转方法,输出字典序最小的那个(矩形的字典序。。。。),如果不能完成翻转,输出IMPOSSIBLE


通过观察可以看出来一共有 2 ^(M*N)种翻转方式,当然不能一种一种的实验,那样会超时到死的,不过通过观察可以看出来只要第一行的翻转方案确认了,那么下面的也可以知道了,因为如果有一个瓷砖需要翻转,本行翻转方法已经确认,那么一定在同列的下行翻转。这样只需要2^15就够了。
写一下试试吧........
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<queue>
using namespace std;

#define maxn 30
const int oo = 0xffffff;

//本身和四周的位置,因为需要保存翻转的方法,所以不改变上层
int dir[4][2] = { {0,0},{0,1},{0,-1},{1,0} };
int G[maxn][maxn], ans[maxn][maxn];
int M, N;

//初始化第0层并且复制图到ans
void Start(int k)
{
    int i, j;

    for(i=N; i>0; i--)
    {
        ans[0][i] = k%2;
        k /= 2;
    }

    for(i=1; i<=M; i++)
    for(j=1; j<=N; j++)
        ans[i][j] = G[i][j];
}
int  OK()//判断翻转后的图是否合法
{
    int i;

    for(i=1; i<=N; i++)
        if(ans[M][i])return 0;

    return 1;
}
//翻转图,并且返回需要翻转的步数,若不能翻转成功则返回-1
int  OverTurn()
{
    int i, j, k, sum=0;

    for(i=1; i<=M; i++)
    for(j=1; j<=N; j++)
    {
        if(ans[i-1][j])
        {
            for(k=0; k<4; k++)
            {
                sum++;
                int ni = i+dir[k][0];
                int nj = j+dir[k][1];

                ans[ni][nj] = !ans[ni][nj];
            }
        }
    }

    if(OK() == 0)
        return -1;

    return sum;
}

int  main()
{
    while(scanf("%d%d", &M, &N) != EOF)
    {
         int i, j, k=pow(2, N);
         int sum = oo, p, q=-1;//sum 需要翻转的步数

         for(i=1; i<=M; i++)
         for(j=1; j<=N; j++)
            scanf("%d", &G[i][j]);

         for(i=0; i<=k; i++)
         {
             Start(i);
             p = OverTurn();

             if(p != -1 && sum > p)
                sum = p, q = i;
         }

         if(q == -1)
            printf("IMPOSSIBLE ");
         else
         {
             Start(q);
             OverTurn();

             for(i=0; i<M; i++)
             for(j=1; j<=N; j++)
                printf("%d%c", ans[i][j], j==N?' ':' ');
         }
    }

    return 0;

} 

原文地址:https://www.cnblogs.com/liuxin13/p/4648351.html