一道搜索的题目,用了状态压缩,把 蛇的身体后面的部分与前一部分的相对位置存储起来,加上头的位置。共有20*20*4^7个状态
然后就是广搜的过程了,先压缩,进队列,解压,然后拓展节点。遇到终点退出。
#include
#include
#include
using namespace std;
const int inf=99999999;
int n,m,l;
int ans[21][21][17000];
int a[21][21];
int x[10],y[10];
struct
{
int t,s,tmp;
}que[1000001];
int bfs()
{
memset(ans,111,sizeof(ans));
int front=1,end=1;
que[1].t=x[1];
que[1].s=y[1];
int tmp=0,txt=1;
for(int i=2;i<=l;i++)
{
int ted;
if(x[i]+1==x[i-1]) ted=0;
else if(x[i]-1==x[i-1]) ted=1;
else if(y[i]+1==y[i-1]) ted=2;
else ted=3;
tmp+=ted*txt;
txt<<=2;
}
//
printf("%d\n",tmp);
que[1].tmp=tmp;
ans[x[1]][y[1]][tmp]=0;
while(front<=end)
{
int t=que[front].t,s=que[front].s,tmp=que[front].tmp;
if(t==1&&s==1) break;
front++;
int tt=tmp;
int t1=t,s1=s;
for(int i=2;i<=l;i++)
{
int ted=tt%4;
tt/=4;
if(ted==0) t1--;
else if(ted==1) t1++;
else if(ted==2) s1--;
else s1++;
a[t1][s1]++;
}
tt=tmp;
int mm=(1<<((l-2)*2))-1;
tt&=mm;
tt<<=2;
if(t+1<=n&&a[t+1][s]==0)
{
if(ans[t+1][s][tt]>ans[t][s][tmp]+1)
{
que[++end].t=t+1;
que[end].s=s;
que[end].tmp=tt;
ans[t+1][s][tt]=ans[t][s][tmp]+1;
}
}
if(t-1>=1&&a[t-1][s]==0)
{
if(ans[t-1][s][tt+1]>ans[t][s][tmp]+1)
{
que[++end].t=t-1;
que[end].s=s;
que[end].tmp=tt+1;
ans[t-1][s][tt+1]=ans[t][s][tmp]+1;
}
}
if(s+1<=m&&a[t][s+1]==0)
{
if(ans[t][s+1][tt+2]>ans[t][s][tmp]+1)
{
ans[t][s+1][tt+2]=ans[t][s][tmp]+1;
que[++end].t=t;
que[end].s=s+1;
que[end].tmp=tt+2;
}
}
if(s-1>=1&&a[t][s-1]==0)
{
if(ans[t][s-1][tt+3]>ans[t][s][tmp]+1)
{
ans[t][s-1][tt+3]=ans[t][s][tmp]+1;
que[++end].t=t;
que[end].s=s-1;
que[end].tmp=tt+3;
}
}
tt=tmp;
t1=t,s1=s;
for(int i=2;i<=l;i++)
{
int ted=tt%4;
tt>>=2;
if(ted==0) t1--;
else if(ted==1) t1++;
else if(ted==2) s1--;
else s1++;
a[t1][s1]--;
}
}
}
int main()
{
int time=0;
while(scanf("%d %d %d",&n,&m,&l),n&&m&&l)
{
time++;
memset(a,0,sizeof(a));
for(int i=1;i<=l;i++)
scanf("%d %d",&x[i],&y[i]);
{
int k;
scanf("%d",&k);
for(int i=1;i<=k;i++)
{
int x,y;
scanf("%d %d",&x,&y);
a[x][y]=1;
}
}
bfs();
int answer=inf;
for(int i=0;i<=16500;i++)
if(answer>ans[1][1][i])
answer=ans[1][1][i];
if(answer!=inf)
printf("Case %d: %d\n",time,answer);
else
printf("Case %d: -1\n",time);
}
return 0;
}