题目大意:贪吃蛇游戏,要到出口所需要的最小步数;
题目解析:bfs的时候因为要考虑到身体的状态所以我们需要借助位运算,来判断下一个蛇的身体和上一个的关系;
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn=25;
int n,m,len,l;
bool rock[maxn][maxn],vis[maxn][maxn][1<<14];
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
struct snake
{
int head_x,head_y;
int shape,step;
snake(int a,int b,int c,int d)
{
head_x=a;
head_y=b;
step=c;
shape=d;
}
snake()
{
head_y=head_x=shape=step=0;
}
};
snake s;
void input_snake()
{
int last_x,last_y;
scanf("%d%d",&s.head_x,&s.head_y);
last_x=s.head_x;
last_y=s.head_y;
s.shape=s.step=0;
for(int i=0;i<l-1;i++)
{
int x,y;
scanf("%d%d",&x,&y);
if(y==last_y)
{
if(x==last_x-1)
s.shape|=0<<(i<<1);
else
s.shape|=1<<(i<<1);
}
else
{
if(y==last_y-1)
s.shape|=2<<(i<<1);
else
s.shape|=3<<(i<<1);
}
last_y=y;
last_x=x;
}
}
bool ok(int x,int y,snake now)
{
int tx=now.head_x;
int ty=now.head_y;
for(int i=0;i<l-1;i++)
{
int d=(now.shape>>(i<<1))&3;
int dx=tx+dir[d][0];
int dy=ty+dir[d][1];
if(dx==x&&dy==y) return false;
tx=dx;
ty=dy;
}
return true;
}
bool can_move(int x,int y,snake now)
{
if(x>=1&&x<=n&&y<=m&&y>=1&&ok(x,y,now)&&!rock[x][y]) return true;
return false;
}
int change_shape(snake now,int d)
{
int ts=now.shape;
ts=ts<<2;
ts&=len;
if(d==0) d=1;
else if(d==1) d=0;
else if(d==2) d=3;
else d=2;
ts|=d;
return ts;
}
int bfs()
{
memset(vis,0,sizeof(vis));
queue<snake>q;
q.push(s);
vis[s.head_x][s.head_y][s.shape]=1;
while(!q.empty())
{
snake now = q.front();
q.pop();
//cout<<now.head_x<<" "<<now.head_y<<endl;
if(now.head_x==1&&now.head_y==1) return now.step;
for(int i=0;i<4;i++)
{
int tx=now.head_x+dir[i][0];
int ty=now.head_y+dir[i][1];
if(!can_move(tx,ty,now)) continue;
snake next;
next.shape=change_shape(now,i);
next.head_x=tx;
next.head_y=ty;
if(!vis[tx][ty][next.shape])
{
vis[tx][ty][next.shape]=1;
next.step=now.step+1;
q.push(next);
}
}
}
return -1;
}
int main()
{
int num_case=1;
while(scanf("%d%d%d",&n,&m,&l)!=EOF&&(n+m+l))
{
memset(rock,0,sizeof(rock));
len=(1<<( (l-1)<<1) )-1;
input_snake();
int k;
scanf("%d",&k);
for(int i=0;i<k;i++)
{
int x,y;
scanf("%d%d",&x,&y);
rock[x][y]=1;
}
printf("Case %d: %d\n",num_case++, bfs());
}
return 0;
}