C ++ 설명 할 수없는 스위치 (재귀, 비트 연산)

"빛을 당기는"게임을 해보셨습니까? 25 개의 조명은 5x5 정사각형으로 배열됩니다. 각 조명에는 스위치가 있으며 플레이어는 상태를 변경할 수 있습니다. 각 단계에서 플레이어는 특정 조명의 상태를 변경할 수 있습니다. 조명의 상태를 변경하는 플레이어는 연쇄 반응을 갖게됩니다.이 조명에 인접한 조명이 위, 아래, 왼쪽 및 오른쪽에 따라 상태가 변경됩니다.
우리는 숫자 "1"을 사용하여 켜짐을 나타내고 숫자 "0"을 사용하여 꺼짐을 나타냅니다. 다음 주
10111
01101
10111
10000
11011
: 빛의 왼쪽 상단의 상태를 변경 한 후가 될 것입니다
01111
11101
10111
10000
11011을
다음 될 것입니다 중간에 빛의 상태를 변경 :
01111
11001
11001
10100
11011는
어떤 주어진 게임의 초기 상태에서 플레이어가 6 단계 내에 모든 조명을 켤 수 있는지 여부를 결정하는 프로그램을 작성합니다.
입력 형식
데이터에서 총 n 개의 미해결 게임 초기 상태를 나타내는 양의 정수 n을 첫 번째 줄에 입력합니다 .
다음 데이터 행은 n 개의 그룹으로 나뉘며 각 데이터 그룹에는 5 개의 행이 있으며 각각 5 개의 문자가 있습니다. 각 데이터 세트는 게임의 초기 상태를 설명합니다. 각 데이터 그룹은 빈 줄로 구분됩니다.
출력 형식
총 n 행의 데이터가 출력되고 각 행에는 6 이하의 정수가 있습니다. 즉, 입력 데이터의 해당 게임 상태가 모든 조명을 켜려면 최소한 몇 단계가 필요합니다.
게임의 특정 초기 상태에서 6 단계 이내에 모든 조명이 켜지지 않으면 "-1"이 출력됩니다.
데이터 범위
0 <n≤500
입력 예 :
3
00111
01011
10001
11010
11100

11101
11101
11110
11111
11111

01111
11111
11111
11111
11111
출력 샘플 :
3
2
-1

AC 코드 :

#include<iostream>
#include<algorithm>
#include<string.h>

using namespace std;

int dx[5]={
    
    1,0,-1,0,0};//坐标偏移量
int dy[5]={
    
    0,-1,0,1,0};//下,左,上,右,原点
char g[6][6];//原状态
char backup[6][6];//原状态备份

void turn(int x,int y)//执行按下(x,y)处开关引发的改变
{
    
    
    for(int i=0;i<5;++i)
    {
    
    
        int a=x+dx[i];
        int b=y+dy[i];
        if(a<0||a>=5||b<0||b>=5) continue;
        g[a][b]^=1;
    }
}

int main()
{
    
    
    int n;
    cin>>n;
    while(n--)
    {
    
    
        for(int i=0;i<5;++i) cin>>g[i];
        memcpy(backup,g,sizeof(g));

        int ans=25;
        for(int i=0;i<32;++i)//枚举第一行的操作
        {
    
    
            int step=0;
            for(int j=0;j<5;++j)//进行第一行的操作
            {
    
    
                if(i>>(4-j)&1){
    
    ++step;turn(0,j);}
            }

            for(int j=0;j<4;++j)//递推之后四行的操作
            {
    
    
                for(int k=0;k<5;++k)
                {
    
    
                    if(g[j][k]=='0'){
    
    ++step;turn(j+1,k);}
                }
            }

            bool dark=false;
            for(int j=0;j<5;++j)//判断是否达到目标
            {
    
    
                if(g[4][j]=='0'){
    
    dark=true;break;}
            }
            if(!dark) ans=min(ans,step);

            memcpy(g,backup,sizeof(backup));//恢复初始状态
        }

        if(ans>6) ans=-1;
        cout<<ans<<endl;
    }
    return 0;
}

추천

출처blog.csdn.net/qq_44643644/article/details/108761137