Flip Game(2021-TRN1-K)

Flip Game(2021-TRN1-K)

General idea

Portal

This is a bit similar to poj 1222 (in fact, the question is a bit more difficult) to the
effect that a chess piece is placed in each grid on a 4*4 chessboard (let's call it a chessboard). The chess pieces are special, one side is black and the other side is white. The color of the chess piece can be changed by flipping the chess piece. Every time a piece is flipped, the color of the piece must change, and the pieces around the piece will also change color accordingly.
Seek the fewest steps.

Problem analysis

A typical DFS does not require too much pruning. This conclusion is drawn because the essence of DFS is enumeration. Obviously, we can choose to open or not open each chess piece, and there are a total of 2^16 possibilities. The amount of calculation is very small. With more grids in poj 1222, the violent DFS may be overtime.
How to enumerate? It is from left to right, top to bottom. Two cases are enumerated: opened, or not opened. This kind of enumeration is not unknown. Then backtrack.

However, when I did it, I was still struggling. I didn’t realize that some chess pieces could not be opened. Also, I wrote DFS for a while. The hand was born. Even step is used as a function parameter. What else needs to be traced back to the beginning? Did not think clearly, the person is gone. . .

Code

#include <bits/stdc++.h>

using namespace std;
int a[5][5];
char str[5][5];
int dir[4][2]={
    
    {
    
    1,0},{
    
    0,1},{
    
    -1,0},{
    
    0,-1}};
int mini=1e8;
int check()
{
    
    
    int i,j,sum=0;
    for(i=1;i<=4;i++)
    {
    
    
        for(j=1;j<=4;j++)
        {
    
    
            sum+=a[i][j];
        }
    }
    if(sum==0||sum==16) return 1;
    return 0;
}
void flip(int x,int y)
{
    
    
    a[x][y]^=1;
    for(int k=0;k<4;k++)
    {
    
    
        int newx=x+dir[k][0];
        int newy=y+dir[k][1];
        if(newx>=1&&newx<=4&&newy>=1&&newy<=4)
        {
    
    
            a[newx][newy]^=1;
        }
    }
}
void dfs(int x,int y,int step)
{
    
    
    if(step>16) return;///16个格子都翻过了,不用继续深搜
    if(check())
    {
    
    
        if(step<mini) mini=step;
        return;
    }
    if(y>=5)
    {
    
    
        x++;
        y=1;
    }
    if(x>=5) return;

    flip(x,y);
    dfs(x,y+1,step+1);///翻开棋子
    flip(x,y);///回溯

    dfs(x,y+1,step);///不翻开棋子
}
void init()
{
    
    
    int i,j;
    for(i=1;i<=4;i++)
    {
    
    
        for(j=0;j<4;j++)
        {
    
    
            if(str[i][j]=='b') a[i][j+1]=1;
            else a[i][j+1]=0;
        }
    }
}
int main()
{
    
    
    int i;
    for(i=1;i<=4;i++)
    {
    
    
        gets(str[i]);
    }
    init();
    dfs(1,1,0);
    if(mini<=16) printf("%d\n",mini);
    else printf("Impossible\n");
    return 0;
}

Guess you like

Origin blog.csdn.net/booniebears/article/details/112971282