zoukankan      html  css  js  c++  java
  • 枚举例题:熄灯问题

    思路:

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

    优化:

      因第一列的状态数为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;
    }
  • 相关阅读:
    选择排序
    迭代器使用过程中为什么抛出ConcurrentModificationException
    自定义实现的ArrayList以及自定义实现的Iterator迭代器
    单链表
    collections方法记录
    JDK1.9中关于集合的新方法
    请使用时间相关的API,计算一个人从出生到现在一共活了多少天?
    java中对象的向上转型和向下转型
    异常相关知识整理
    可变参数相关知识
  • 原文地址:https://www.cnblogs.com/ShadowCharle/p/10735572.html
Copyright © 2011-2022 走看看