状态压缩搜索——【USACO2.2.4】派对灯

一开始看还以为状态100种,搜索深度10000层,明显要爆内存或时间
看了nocow解释,每种状态里每六个灯循环,就可以将基础状态找出:(按钮4:当按下此按钮,将改变所有序号是3*K+1(K>=0)的灯。例如:1,4,7... )这里可以发现循环
一共就8种
bool map[8][6]={
{0,0,0,0,0,0},
{0,0,1,1,1,0},
{0,1,0,1,0,1},
{0,1,1,0,1,1},
{1,0,0,1,0,0},
{1,0,1,0,1,0},
{1,1,0,0,0,1},
{1,1,1,1,1,1}};
bu[8]={1,2,1,1,2,1,2,0};//达到每种状态的步数
c==0 搜状态
c==1 搜
c>=1 搜
然后就是要注意没有可能的状态,则输出一行'IMPOSSIBLE'就行了……
View Code
#include<stdio.h>

bool map[8][6]=
{
{
0,0,0,0,0,0},
{
0,0,1,1,1,0},
{
0,1,0,1,0,1},
{
0,1,1,0,1,1},
{
1,0,0,1,0,0},
{
1,0,1,0,1,0},
{
1,1,0,0,0,1},
{
1,1,1,1,1,1}
};



int bu[8]={1,2,1,1,2,1,2,0};
bool kai[6];
bool guan[6];

int main()
{
int temp,n,c,add;
while(scanf("%d",&n)!=EOF)
{
int i,j;
for(i=0;i<6;i++)
{
kai[i]
=0;
guan[i]
=0;
}
scanf(
"%d",&c);
while(scanf("%d",&temp),temp!=-1)
{
kai[(temp
-1)%6]=1;
}
while(scanf("%d",&temp),temp!=-1)
{
guan[(temp
-1)%6]=1;
}

bool one=0,hou=0;
if(c==0)
{
for(i=0;i<6;i++)
{
if(guan[i]==1)
{
printf(
"IMPOSSIBLE\n");
one
=1;
break;
}
}

if(one==0)
{
for(i=0;i<n;i++)
{
printf(
"1");
}
printf(
"\n");
}
}
else if(c==1)
{
for(i=0;i<8;i++)
{
if(bu[i]>1) continue;

add
=0;
for(j=0;j<6;j++)
{
if(kai[j]==1)
{
if(map[i][j]==1)
{}
else
break;
}
if(guan[j]==1)
{
if(map[i][j]==0)
{}
else
break;
}
add
++;
}
int k;
if(add==6)
{
hou
=1;
for(k=0;k<n;k++)
printf(
"%d",map[i][k%6]);
printf(
"\n");
}
}
if(hou==0)
printf(
"IMPOSSIBLE\n");
}
else
{
for(i=0;i<8;i++)
{

add
=0;
for(j=0;j<6;j++)
{
if(kai[j]==1)
{
if(map[i][j]==1)
{}
else
break;
}
if(guan[j]==1)
{
if(map[i][j]==0)
{}
else
break;
}
add
++;
}
int k;
if(add==6)
{
hou
=1;
for(k=0;k<n;k++)
printf(
"%d",map[i][k%6]);
printf(
"\n");

}
}
if(hou==0)
printf(
"IMPOSSIBLE\n");
}
}
}
原文地址:https://www.cnblogs.com/huhuuu/p/1980242.html