熄灯问题+(进阶)

https://vjudge.net/problem/OpenJ_Bailian-2811

熄灯问题是比较典型的算法题目(枚举),这里展示两种解法,供大家参考:

解发一:

#include <iostream>
#include<string>
#include<cstring>
#include<memory>
using namespace std;
char oriLights[5];
char lights[5];
char result[5];

int GetBit(char c,int i)
{
    return (c>>i)&1;
}
void SetBit(char & c,int i,int v)
{
    if(v){
        c|=(1<<i);
    }
    else
        c &= ~(1<<i);
}

void FlipBit(char & c,int i)
{
    c ^= (1<<i);
}

void OutputResult(int t,char result[])
{
    cout << "PUZZLE #" << t << endl;
    for(int i=0;i<5;++i){
        for(int j = 0;j<6;++j){
            cout << GetBit(result[i],j);
            if( j<5)
                cout <<" ";
        }
        cout << endl;
    }
}

int main()
{
    int T;
    cin >> T;
    for(int t=1;t<=T;++t){
        for(int i=0;i<5;++i)
            for(int j=0;j<6;++j){
                int s;
                cin>>s;
                SetBit(oriLights[i],j,s);
        }
        for(int n=0;n<64;++n){
            int switchs = n;
            memcpy(lights,oriLights,sizeof(oriLights));
            for(int i=0;i<5;++i){
                result[i] = switchs;
                for(int j=0;j<6;j++){
                    if(GetBit(switchs,j)){
                        if(j>0)
                            FlipBit(lights[i],j-1);
                        FlipBit(lights[i],j);
                        if(j<5)
                            FlipBit(lights[i],j+1);
                    }
                }
                if(i<4)
                lights[i+1] ^= switchs;
                switchs = lights[i];
            }
            if(lights[4] == 0){
                OutputResult(t,result);
                break;
            }
        }
    }
    return 0;
}

解法二:


#include<stdio.h>
int press[6][8];
int puzzle[6][8];
bool  guess()
{
    int i,j;
    for(i=2;i<=5;i++){
        for(j=1;j<=6;j++)
        {
            press[i][j]=( press[i-1][j]
                            + puzzle[i-1][j]
                            + press[i-1][j-1]
                            + press[i-2][j]
                            + press[i-1][j+1] ) %2;
        }
    }
    for(j=1;j<=6;j++){
        if(puzzle[5][j] != (press[5][j]+press[5][j+1]+press[5][j-1]+press[4][j])%2)
        return false;
    }
    return true;

}

void process()
{
    int c;
    for(c=1;c<=6;c++)
        press[1][c]=0;
        while(!guess())
        {
                press[1][1]++;
                c=1;
                while(press[1][c]>1)
                {
                    press[1][c]=0;
                    c++;
                    press[1][c]++;
                }
        }
}

int main()
{
     int t,i,n,j;
    for(i=0;i<8;i++)
    press[0][i]=puzzle[0][i]=0;
    for(i=1;i<6;i++)
        press[i][0]=puzzle[i][0]=press[i][7]=puzzle[i][7]=0;

    for(i=1;i<=5;i++)
        for(j=1;j<=6;j++)
            scanf("%d",&puzzle[i][j]);

    process();

    for(i=1;i<=5;i++){
        for(j=1;j<=6;j++){
            printf("%d ",press[i][j]);
        }
        printf("\n");
    }
    return 0;
}

其实熄灯问题可以有一个进阶版,对于每一个初始状态的输入(灯的状态)至少有1种解,我们只是求出了其中的一个解.     

如果要求出全部解,这又是一个新的问题。(有空可以好好思考思考!)

猜你喜欢

转载自blog.csdn.net/wl20222022/article/details/82709481