标签:
题意很简单,可以看翻译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; }
标签:
原文地址:http://www.cnblogs.com/modengdubai/p/4781103.html