zoukankan      html  css  js  c++  java
  • POJ

    #include <iostream>
    #include <memory>
    #include <cstring>
    #include <string>
    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);//与1进行异或运算则翻转
        //与0进行异或运算则不变
    }
    
    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++) {
            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));//第i行的开关状态
                int switchs = n;
                for (int i = 0; i < 5;i++) {
                    result[i] = switchs;//第i行的开关方案
                    for (int j = 0; j < 6;j++) {
                        if (GetBit(switchs,j)) {//如果i行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;//改第i+1行的灯,还是异或运算的应用
                        //如果上一行按了,势必会影响下一行
                    }
                    switchs = Lights[i];//为了灭掉第i行还未被灭掉的灯,所以将i+1行的开关方案设置为第i行灯亮的情况
                    //1表示按下,0表示不按,1表示灯亮,0表示灯灭,正好一一对应
                }
                if (Lights[4]==0) {
                        OutputResult(t, result);
                        break;
                    }
            }
        }
        getchar();
        getchar();
        return 0;
    }

    Lights[ i ] 是结果数组,oriLights[ i ] 是读入时的矩阵,result [ i ] 是存翻转方案的矩阵。

    对这个题用的是枚举的思路,但是如果全部枚举的话就是 2 的 30 次方,所以我们只枚举第一行,就是2 的 6 次方。

    因为当你的第一行按下之后,之后的四行都是要为第一行服务的,所以也就是说为了让第一行为 0 ,就要让第二行的熄灯方案

    为第一行还亮着的灯的位置。

    只有这样才能把之前第一行未熄灭的灯给熄灭掉,但是代码中并没有再次修改上一行灯的状态,我们只是假修改一下。

    实际上并未修改,因为这样并不会影响我们继续执行下一行的熄方案,我们只是知道它已经被修改了就行了。

    这样的话第二行就确定了,因此也就没有必要去枚举了。然后第三行和第四行以此类推,所以我们只需要枚举第一行。

  • 相关阅读:
    Redis数据类型和基本操作
    Redis持久化
    Redis安装
    MySQL5.7二进制包安装
    Django ORM多表操作
    Django中启用事务
    Django ORM单表操作
    MySQL事务
    用顺序栈实现十进制向二进制转化
    顺序栈
  • 原文地址:https://www.cnblogs.com/xyqxyq/p/10211368.html
Copyright © 2011-2022 走看看