题目链接:http://poj.org/problem?id=1324
模拟贪吃蛇行走到(1,1)方块的最短距离,有障碍物。
错了2次,第一次内存超了,把队列改成stl的,第二次是有起点就是终点的数据。
状态压缩思路:记录蛇头坐标,并记录下一个蛇方块是在该方块的哪个方向,0,1,2,3分别对上,下,左,右。
然后就可以bfs了。
/*--------------------------------------------------------
Author:log
Created Time:2016年04月15日 星期五 18时33分42秒
--------------------------------------------------------*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <map>
using namespace std;
const int maxn=22;
const int maxl=9;
bool grap[maxn][maxn];
int n,m,L,k;
int a[maxl],b[maxl];
int state[maxl];
bool vis[maxn][maxn][1<<14];
int dx[4]={1,0,-1,0};
int dy[4]={0,-1,0,1};
struct Node{
int x,y;
int st;
int d;
Node(){x=y=st=d=0;}
Node(int x,int y,int st,int d):x(x),y(y),st(st),d(d){}
};
queue<Node>q;
bool check(int x,int y,Node u){
int _x=u.x,_y=u.y;
int sp=3;
int tmp;
for(int i=L-2;i>=0;i--){
tmp=(((u.st>>(i*2))&sp)+2)%4;
_x+=dx[tmp];
_y+=dy[tmp];
// printf(" %d %d\n",_x,_y);
if(_x==x&&_y==y)return false;
}
return true;
}
int getstate(int i,int s){
s>>=2;
i<<=(2*(L-2));
return s|i;
}
int bfs(){
if(a[0]==1&&b[0]==1)return 0;
while(!q.empty())q.pop();
memset(vis,0,sizeof(vis));
Node u;
u.x=a[0];u.y=b[0];
for(int i=1;i<L;i++){
u.st<<=2;
u.st|=state[i];
}
q.push(u);
vis[u.x][u.y][u.st]=true;
int x,y,st;
while(!q.empty()){
u=q.front();q.pop();
// printf("%d:%d %d %d %d\n",l,u.x,u.y,u.st,u.d);
for(int i=0;i<4;i++){
x=u.x+dx[i];
y=u.y+dy[i];
st=getstate(i,u.st);
if(x<=0||x>n||y<=0||y>m||grap[x][y])continue;
if(!check(x,y,u))continue;
if(vis[x][y][st])continue;
// printf("%d %d %d\n",x,y,st);
if(x==1&&y==1)return u.d+1;
vis[x][y][st]=true;
q.push(Node(x,y,st,u.d+1));
}
}
return -1;
}
int main(){
int head;
int t=0;
while(scanf("%d %d %d",&n,&m,&L)==3&&(n||m||L)){
memset(grap,0,sizeof(grap));
for(int i=0;i<L;i++){
scanf("%d %d",&a[i],&b[i]);
if(i!=0){
if(a[i]==a[i-1]-1)state[i]=0;
else if(b[i]==b[i-1]+1)state[i]=1;
else if(a[i]==a[i-1]+1)state[i]=2;
else state[i]=3;
}
}
scanf("%d",&k);
int a,b;
for(int i=0;i<k;i++){
scanf("%d %d",&a,&b);
grap[a][b]=true;
}
printf("Case %d: %d\n",++t,bfs());
}
return 0;
}