您的位置:首页 > 其它

usaco Party Lamps

2015-09-04 01:39 239 查看
题意很简单,可以看翻译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;
}


  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: