这题乍一看吓一跳...范围挺大的...想了也有一个小时才想通...看清本质!!

    总共就4个按钮...如果我1,2,3,4都按过一次了..再按一下1 or 2 or 3 or 4灯的情况不和只按了2,3,4 or 1,3,4 or 1,2,4 or  1,2,3一样吗?因为一个按钮按两次就相当于没按..那么实际上能出现的最多情况也就是C(1,4)+C(2,4)+C(3,4)+C(4,4)=17种~~枚举出这些情况..当且仅当当前所案件的次数与所需要的按键次数之差为偶数(不断地来回按)并且得到的情况是满足输入的要求的就找到了一个~~

    输出的话再排个序行了~~

Program:

/*  
ID: zzyzzy12
LANG: C++
TASK: lamps
*/
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<queue>
using namespace std;
struct node
{
int s[102];
}ans[1001],h;
int N,C,x,s[102],num;
bool f;
bool cmp(node a,node b)
{
int i;
for (i=1;i<=N;i++)
if (a.s[i]!=b.s[i]) return a.s[i]<b.s[i];
}
void search(node h,int step,int key)
{
int i,j;
node k;
if (step<=C && (C-step)%2==0)
{
for (i=1;i<=N;i++)
if (s[i]!=-1 && s[i]!=h.s[i]) goto A;
ans[++num]=h;
if (num!=1)
{
for (i=1;i<num;i++)
{
f=true;
for (j=1;j<=N;j++)
if (ans[num].s[j]!=ans[i].s[j]) f=false;
if (f) break;
}
if (f) num--;
}
}
A: ;
for (i=key;i<=4;i++)
{
if (i==1)
{
k=h;
for (j=1;j<=N;j++) k.s[j]=1-k.s[j];
}
else
if (i==2)
{
k=h;
for (j=1;j<=N;j++) if (j%2) k.s[j]=1-k.s[j];
}
else
if (i==3)
{
k=h;
for (j=1;j<=N;j++) if (j%2==0) k.s[j]=1-k.s[j];
}
else
if (i==4)
{
k=h;
for (j=1;j<=N;j++) if (j%3==1) k.s[j]=1-k.s[j];
}
search(k,step+1,key+1);
}
}
int main()
{
freopen("lamps.in","r",stdin);
freopen("lamps.out","w",stdout);
scanf("%d%d",&N,&C);
memset(s,-1,sizeof(s));
while (scanf("%d",&x) && x!=-1) s[x]=1;
while (scanf("%d",&x) && x!=-1) s[x]=0;
num=0;
for (int i=1;i<=N;i++) h.s[i]=1;
search(h,0,1);
if (num)
{
sort(ans+1,ans+1+num,cmp);
int j,i;
for (i=1;i<=num;i++)
{
for (j=1;j<N;j++) printf("%d",ans[i].s[j]);
printf("%d\n",ans[i].s[N]);
}
}else printf("IMPOSSIBLE\n");
return 0;
}