码迷,mamicode.com
首页 > 其他好文 > 详细

usaco Party Lamps

时间:2015-09-04 07:26:26      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:

 题意很简单,可以看翻译http://www.wzoi.org/usaco/13%5C104.asp

 因为同一个开关按两次的等于没按,所以当C大于4时,可以将C一直减2,减到小于等于4为止,然后开始枚举,分析题目之后发现可以用一个6位二进制表示前6个等,后面的等每6个和前面的一样

0和1异或上0不变,异或上1之后0变1,1变0

给当前状态异或上不同的二进制就是按了开关之后的状态。

DFS就能解

/*
ID: modengd1
PROG: lamps
LANG: C++
*/
#include <iostream>
#include <stdio.h>
#include <memory.h>
using namespace std;
int counter;
int N;
bool vis[1<<7];
int on[64];
int off[64];
int op1=0x3F;
int op2=0x15;//010101
int op3=0x2A;//101010
int op4=0x24;//100100
void slove(int C,int N,int deep,int lamp)
{
    if(deep==C)
    {
        for(int i=0;on[i]!=-1;i++)
        {
            if((lamp&(1<<(5-(on[i]-1)%6)))==0)
                return;
        }
        for(int i=0;off[i]!=-1;i++)
        {
            if((lamp&(1<<(5-(off[i]-1)%6)))!=0)
                return;
        }
        vis[lamp]=true;
        return ;
    }
    slove(C,N,deep+1,lamp^op1);
    slove(C,N,deep+1,lamp^op2);
    slove(C,N,deep+1,lamp^op3);
    slove(C,N,deep+1,lamp^op4);
}
int main()
{
    freopen("lamps.in","r",stdin);
    freopen("lamps.out","w",stdout);
    int C,N;
    memset(vis,false,sizeof(vis));
    scanf("%d",&N);
    scanf("%d",&C);
    for(int i=0;scanf("%d",&on[i])&&on[i]!=-1;i++)
        ;
    for(int i=0;scanf("%d",&off[i])&&off[i]!=-1;i++)
        ;
    while(C>4)
        C-=2;
    slove(C,N,0,0x3F);
    bool impossivle=true;
    for(int i=0;i<(1<<6);i++)
    {
        if(vis[i])
        {
            impossivle=false;
            for(int j=0;j<N;j++)
                if(i&(1<<(5-j%6)))
                    cout<<1;
                else
                    cout<<0;
            cout<<endl;
        }
    }
    if(impossivle)
        cout<<"IMPOSSIBLE"<<endl;
    return 0;
}

  

usaco Party Lamps

标签:

原文地址:http://www.cnblogs.com/modengdubai/p/4781103.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!