枚举例题:熄灯问题

 

 

 

 

 

思路:

  枚举第一行所有状态,则第二行由第一行灯的状态决定,以此类推。(若要将上一行开着的灯关闭,在下一行只能拨动对应列的开关)

优化:

  因第一列的状态数为2**6=64,因此可用一个整数表示所有情况,通过位运算来实现相应位的改变。

 

代码如下:

  

#include<iostream>
#include<memory>
#include<cstring>
#include<string>
using namespcae std;

int GetBit(char c,int i)
{
    //取c的第i位
    return ( c >> i ) & 1; 
}
void SetBit(char &c,int i,int v)
{
     //设置c第i位为v
    if(v)
         c |= ( 1 << i );
    else
        c &= ~( 1 <<i );
}
void Flip(char &c,int i)
{
    //将c的第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()
{
    char oriLights[5];    //原始的等矩阵 
    char  lights[5];        //寄存矩阵,灯变化的结果存放这里 
    char  result[5];        //结果
    char switchs;    //表示某一行的灯开关方案 
    int T;
    cin>>T;
    for(int t=1;t<=T;t++)
    {
        memset(oriLights,0,sizeof(oriLights));
        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++)
        {
            memcpy(lights,oriLights,sizeof(oriLights));
            switchs = n;    第1行的开关状态 
            for(int i=0;i<5;i++)
            {
                result[i] = switchs;    //第i行的开关方案 
                for(int j=0;j<6;j++)
                {
                    if(GetBit(switchs,j))
                    {
                        if(j>0)
                            Flip(lights[i],j-1);    //改左灯
                        Flip(lights[i],j);
                        if(j<4)
                            Flip(lights[i],j+1); 
                    }
                }
                if(i<4)
                    lights[i+1]    ^= switchs;    //改下一行的灯
                switchs = lights[i]; //第i+1行的开关方案就是第i行的灯开关状态 
            }
            if(ligths[4] == 0)
            {
                OutputResult(t,result);
                break;
            }
        }
    }
    return 0;
}

 

posted @ 2019-04-19 14:02  吉光一片羽  阅读(212)  评论(0编辑  收藏  举报