POJ-1222EXTENDED LIGHTS OUT-位运算枚举模板

传送门:http://poj.org/problem?id=1222

题意:开关灯问题,一幅开关的灯中,给出一种操作,使得灯全关掉,(操作一个开关,相邻的灯也会改变)

思路:利用位运算枚举第一行;

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <string>
using namespace std;

char orilights[10],lights[10],ans[10];

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 Output(int t)
{
    cout<<"PUZZLE #"<<t<<endl;
    for(int i=0; i<5; ++i)
    {
        for(int j=0; j<6; ++j)
        {
            cout<< GetBit(ans[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);
            }
        }
        //cout<<1<<endl;
        for(int n=0; n<64; ++n)
        {
            int switchs = n;
            memcpy(lights,orilights,sizeof(orilights));
            for(int i=0; i < 5; ++i)
            {
                ans[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)
            {
                Output(t);
                break;
            }

        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/ckxkexing/p/8933023.html

时间: 2024-11-07 09:01:23

POJ-1222EXTENDED LIGHTS OUT-位运算枚举模板的相关文章

hdu 1882 Strange Billboard(位运算+枚举)

http://acm.hdu.edu.cn/showproblem.php?pid=1882 感觉非常不错的一道题. 给一个n*m(1<=n,m<=16)的矩阵,每一个格子都有黑白两面,当翻一个格子时,它的上下左右都要翻转,问最后使格子全变为白色的最少翻转步数. 仅仅需枚举第一行的状态即可,由于对于第i(i>=2)行j列翻转情况受上一行的制约,仅仅有当上一行也是'X'的时候,该行j列才干翻转,使i-1行j列变为'.',否则i行j列不能翻转.依次进行下去,当最后一行全变为白色,说明翻转成功

位运算+枚举

位运算http://c.biancheng.net/cpp/html/101.html 在很多情况下(比如翻棋子)在搜索时涉及大量枚举往往导致超时,位运算则很好地解决了这个问题,方便又快捷 HDU  1882   Strange Billboard http://acm.hdu.edu.cn/showproblem.php?pid=1882 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot

[hdoj]3006//位运算+枚举

题意:给出n个集合,问这些集合能组合成几种不同的集合. 思路:枚举+状态压缩.由于1<=m<=14,所以最多有2^14=16 384种状态,每种状态可以存在一个int中.枚举所有的状态,运用位运算,判断能否由这n个集合组成. #include<iostream> using namespace std; int main(){ int n, m, k, w, i, j; int ans, val[105]; while(cin >> n >> m){ for

在C#中对枚举进行位运算--枚举组合

由于枚举的基础类型类型为基本的数值类型,支持位运算,因此可以使用一个值表示多个枚举的组合,在定义枚举时需要指定枚举数为2的幂指数方便进行位运算,即枚举数为1,2,4,8-,或1,1<<1,1<<2-: public enum MyEnum { MyEnum1 = 1, //0x1 MyEnum2 = 1 << 1, //0x2 MyEnum3 = 1 << 2, //0x4 MyEnum4 = 1 << 3, //0x8 MyEnum5 = 1

POJ 1166 The Clocks 位运算与BFS

1.题意:有一组3*3的只有时针的挂钟阵列,每个时钟只有0,3,6,9三种状态:对时针阵列有9种操作,每种操作只对特点的几个时钟拨一次针,即将时针顺时针波动90度,现在试求从初试状态到阵列全部指向0的状态所需要的最小操作数的操作方案: 2.输入输出:输入给出阵列初始状态,0,1,2,3分别表示0,3,6,9:要求输出最快方案的操作序列: 3.分析:IOI 1994的考题,BFS是比较容易想到的方法之一,关键是如何简洁的表示和改变BFS过程中的阵列状态:这里使用位运算的方法:具体如下: 首先一共9

POJ 2777 Count Color(位运算+线段树+lazy+区间更新)

Count Color Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 39905   Accepted: 12034 Description Chosen Problem Solving and Program design as an optional course, you are required to solve all kinds of problems. Here, we get a new problem.

POJ1222熄灯问题【位运算+枚举】

EXTENDED LIGHTS OUT Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14231   Accepted: 8817 Description In an extended version of the game Lights Out, is a puzzle with 5 rows of 6 buttons each (the actual puzzle has 5 rows of 5 buttons ea

poj 3225 线段树+位运算

略复杂的一道题,首先要处理开闭区间问题,扩大两倍即可,注意输入最后要\n,初始化不能随便memset 采用线段树,对线段区间进行0,1标记表示该区间是否包含在s内U T S ← S ∪ T 即将[l,r]标记为1I T S ← S ∩ T 即将-oo~l和r~+oo标记为0,因为是并集,所以并集后的集合s一定在[l,r]内,则在l,r内的集合被标记是什么状态就是什么状态(表示是否属于s),[l,r]外的集合不属于s所以标记为0D T S ← S - T  即将[l,r]标记为0,则在[l,r]内

POJ2965 位运算+枚举

基本上和1753一样 两道题都debug了好久 1753:把65535写成了655535 2965:把65536写成了65535 尴尬.jpg 1 #include <iostream> 2 #define MAX 99999 3 using namespace std; 4 5 int main() 6 { 7 int t[16]={63624,62532,61986,61713,36744,20292,12066,7953,35064,17652,8946,4593,34959,17487