Convoluted switch (bit recursive calculation +)

You played "pull light" games? 25 lights arranged in a 5x5 square. Each lamp has a switch, the player can change its state. Each step, the player can change the state of a particular lamp. The player to change the state of a lamp produces a chain reaction: up and down about the lamp and the lamp should be adjacent to change its state.

We use the number "1" indicates an open lamp, shown by numeral "0" indicates OFF the lamp. Below this state

10111
01101
10111
10000
11011
after changing the state of the top left corner of the lamp becomes:

01111
11101
10111
10000
11011
then change the state of the middle of the lamp becomes:

01111
11001
11001
10100
11011
given initial state of some games, the player determines whether or programming may make all the lights within the step 6 are both on.

Input format
of the first input line nn positive integer, data representative of a total of nn game to be solved initial state.

Nn is divided into the following several lines of data groups, each data row 5, 5 characters per line. Each set of data describes the initial state of a game. Between groups of data separated by a blank line.

Output format
total output nn rows, each row has an integer less than or equal to 6, it indicates to the game state corresponding to the input data requires a minimum of steps to make all lit..

For a certain initial state of the game, if not all steps within 6 is lit, the output "-1."

Data range
0 <n≤5000 <n≤500
Input Sample:
. 3
00111
01011
10001
11010
11100

11101
11101
11110
11111
11111

01111
11111
11111
11111
11111
sample output:

3
2
-1

Thinking: enumeration of all states by the first discharge switch (enumeration using bit operation), then the state of the first to fourth row from all the lamps, if closed, to press the lamp switch below it (the last row enumeration does not need, because no light below it). After traversed to see if the last row of lights on, and if so, explain the legitimate operation, maintenance at a minimum.

#include<iostream>
#include<cstring>
using namespace std;
#define inf 10000000
char a[10][10];
int nex[5][2]={{0,0},{0,1},{0,-1},{1,0},{-1,0}};
void turn(int x,int y)   //改变周围五个位置的状态
{
    for(int i=0;i<5;i++)
    {
        int xx=x+nex[i][0];
        int yy=y+nex[i][1];
        if(xx>=0 && xx<5 && yy>=0 && yy<5)
        {
            a[xx][yy]^=1;
        }
    }
}
int work()
{
    
    int ans=inf;
    for(int k=0;k< 1<<5;k++)  //按位枚举第一排按灯的所有可能性
    {
        char tem[10][10];
         memcpy(tem,a,sizeof tem);    //保留状态,枚举完以后会用到
        int res=0;
        for(int i=0;i<5;i++)
            if(k>>i & 1)   //如果k的第i位是1,第一排的第i位需要被按一下
            {
                turn(0,i);
                res++;
            }
        for(int i=0;i<4;i++)     //枚举1-4for(int j=0;j<5;j++)
            {
                if(a[i][j]=='0')
                {
                    turn(i+1,j);
                    res++;
                }
            }
        int flag=0;
        for(int i=0;i<5;i++)   //判断操作是否合法
            if(a[4][i]=='0')
            {
                flag=1;break;
            }
        memcpy(a,tem,sizeof a);   //恢复状态
        if(flag)
            continue;
        ans=min(ans,res);
        
    }
    if(ans>6)
        return -1;
    return ans;
}
int main()
{
    int n;
    cin>>n;
    while(n--)
    {
        for(int i=0;i<5;i++)
            cin>>a[i];
        cout<<work()<<endl;
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/weixin_43693379/article/details/90484176