Fliptile (反转模拟或者dfs)

题目来源:https://vjudge.net/contest/159739#problem/D
【题意】
给你0 1相间的矩阵砖块,反转之后得到相反的数,但是反转一个砖块,他的上下左右全都会反转,问,能不能把所有的1反转成0,最少需要多少步。
【思路】
首先,这道题我说的会比较详细,因为这道题比较好玩,不仅用到了二进制状态压缩,还用了模拟,或者是dfs。下面是我的叙述:
我们的思路可以是这样的,先把第一行给确定了,然后通过下一行进行反转得到想要的,然后下一行在通过下下一行的反转来确定,就这样一直循环到最后一行,到最后一行的时候,假如最后一行都是0,那说明此时的第一行的状态是可以的,如果有一个不为0,那么就说明这个状态不可取。然后无论可取不可取,都要换一个第一行的状态,在继续,因为要找到最小值。
然后,这一种做法每一个砖块最多只会反转一次(我说的是主动的,不是受影响的),最少是0次;下面解释一下我的代码。
在我的代码里,二进制状态压缩,也就是 int row=1《《m,意思是第一行的 每一种状态,举个例子,0 0 0 1这是一种状态,那么压缩成二进制然后换成十进制就是1,0 1 0 1就是5,那么当m等于4 的时候有多少种状态呢,有2^4种,换成位运算,就变成了左移运算符《《,状态有了,接下来便是一个一个的遍历,那么我的M二维数组是做什么的呢,是用来记录某个位置反转了多少次,而judge函数就是用来判断一下,经过了他自己或者是周围的点反转之后,当前点记录的是1还是0,然后通过这个来判断他同列的下一行那个砖块是否需要反转。而G数组记录的是最优的状态。
【代码】

#include
#include
#include
#include
#include
#include
#include
#include
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long LL;
int d[5][2]= {{0,0},{0,1},{0,-1},{1,0},{-1,0}};
int n,m;
int mp[16][16];
int M[16][16];
int G[16][16];
bool judge(int x,int y)
{
    int res=mp[x][y];
    for(int i=0; i<5; i++)
    {
        int rx=x+d[i][0];
        int ry=y+d[i][1];
        if(rx>=0&&rx=0&&ryreturn res&1;
}
int check()
{
    for(int i=1; ifor(int j=0; jif(judge(i-1,j)!=0)
                M[i][j]=1;
    for(int i=0; iif(judge(n-1,i)!=0)
            return -1;
    int res=0;
    for(int i=0; ifor(int j=0; jreturn res;

}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        for(int i=0; ifor(int j=0; jscanf("%d",&mp[i][j]);
        int row=1<int sum=0,ans=-1;
        for(int i=0; i0);
            for(int j=0; j0][m-j-1]=i>>j&1;
            sum=check();
            if(sum>=0&&(ans<0||ans>sum))
            {
                ans=sum;
                memcpy(G,M,sizeof(M));
            }
        }
        if(ans==-1)
            printf("IMPOSSIBLE\n");
        else
        {
            for(int i=0; iprintf("%d",G[i][0]);
                for(int j=1; jprintf(" %d",G[i][j]);
                }
                printf("\n");
            }
        }

    }
}

你可能感兴趣的:(ACM竞赛,【搜索】--深搜,【强行模拟,最为致命】,ACM的进程)