题目链接:USACO - Party Lamps
观察后可以发现所有数字都与前4个数字有关。
1:所有
3k+1
的奇数
2:所有非
3k+1
的偶数
3:所有非
3k+1
的奇数
4:所有
3k+1
的偶数
而这四个灯只有16种状态,所以直接搜索然后判断即可。
/*
ID: xdujlx1
PROG: lamps
LANG: C++
*/
#include<bits/stdc++.h>
using namespace std;
int b[4]={10,5,9,15};
bool vis[16];
int ini[107];
int c,n;
void ioinit()
{
freopen("lamps.in","r",stdin);
freopen("lamps.out","w",stdout);
}
void bfs()
{
queue<pair<int,int> > q;
q.push(make_pair(15,0));
int cur=0;
vis[15]=true;
while(!q.empty())
{
pair<int,int> p=q.front();q.pop();
if(p.second>=c) break;
if(p.second>cur)
{
cur=p.second;
memset(vis,0,sizeof(vis));
}
for(int i=0;i<4;i++)
{
int t=p.first^b[i];
if(!vis[t])
{
q.push(make_pair(t,p.second+1));
vis[t]=true;
}
}
}
}
vector<int> get_ans(int k)
{
vector<int> a;
for(int i=0;i<107;i++) a.push_back(0);
a[1]=k&1;a[2]=(k>>1)&1;a[3]=(k>>2)&1;a[4]=(k>>3)&1;
for(int i=5;i<=n;i+=2) if(i%3!=1) a[i]=a[3]; else a[i]=a[1];
for(int i=6;i<=n;i+=2) if(i%3!=1) a[i]=a[2]; else a[i]=a[4];
return a;
}
bool check(vector<int> & ans)
{
for(int i=1;i<=n;i++)
{
if(ini[i]==-1) continue;
if(ini[i]^ans[i]) return false;
}
return true;
}
bool operator < (const vector<int> & a, const vector<int> & b)
{
for(int i=1;i<=n;i++)
if(a[i]!=b[i]) return a[i]<b[i];
return false;
}
int main()
{
ioinit();
int t;
scanf("%d%d",&n,&c);
memset(ini,-1,sizeof(ini));
while(scanf("%d",&t))
{
if(t==-1) break;
ini[t]=1;
}
while(scanf("%d",&t))
{
if(t==-1) break;
ini[t]=0;
}
bfs();
vector<vector<int> > aans;
for(int i=0;i<16;i++)
{
if(vis[i])
{
vector<int> ans=get_ans(i);
if(check(ans)) aans.push_back(ans);
}
}
sort(aans.begin(),aans.end());
for(int i=0;i<aans.size();i++)
{
vector<int> & ans=aans[i];
for(int j=1;j<=n;j++)
printf("%d",ans[j]);
puts("");
}
if(aans.size()==0) puts("IMPOSSIBLE");
return 0;
}