题意:有一只在n*m(1<=n,m<=15)的迷宫内,蛇头为1,身长<=9,@为苹果,#为墙,问最小几步能吃到苹果。吃不到输出-1.
题解:hash存储两个相邻蛇身的关系上下左右四种状态用两位二进制表示,dis[ i ][ j ][ t ] 表示蛇头在i j 位置蛇身状态为 t 的时候的最小步数,然后bfs即可。
Sure原创,转载请注明出处。
[cpp]
#includ ((a) > (b) (a) : (b))
using namespace std;
const int maxn = 20;
const int maxt = 1 《 17;
const int move = {{-1,0},{0,1},{1,0},{0,-1}};
struct ddd
{
int x,y,s;
};
char map[maxn][maxn];
int st [maxn 》 1],dis[maxn][maxn][maxt];
bool vis[maxn][maxn][maxt];
queue <ddd> Q;
int m,n,len,edx,edy;
int hash()
{
int res = 0;
for(int i=len-1;i>0;i--)
{
for(int j=0;j<4;j++)
{
if(st[0][i-1] + move[j][0] == st[0][i] && st [i-1] + move[j] == st [i])
{
res 《= 2;
res |= j;
}
}
}
return res;
}
bool judge(int x,int y,int px,int py,int ss)
{
if(x >= 0 && y >= 0 && x < m && y < n && map[x][y] != '#')
{
int ppx = px + move[ss&3][0];
int ppy = py + move[ss&3] ;
if(ppx == x && ppy == y) return false;
st[0][0] = x;
st [0] = y;
st[0] = px;
st = py;
for(int i=2;i<len;i++)
{
int d = ss & 3;
px += move[d][0];
py += move[d] ;
if(px == x && py == y) return false;
st[0][i] = px;
st [i] = py;
ss 》= 2;
}
return true;
}
return false;
}
void read()
{
memset(vis,false,sizeof(vis));
len = 0;
for(int i=0;i<m;i++)
{
scanf("%s",map[i]);
for(int j=0;j<n;j++)
{
if(map[i][j] >= '1' && map[i][j] <= '9')
{
int tmp = map[i][j] - '1';
st[0][tmp] = i;
st [tmp] = j;
len = MAX(len , tmp+1);
}
if(map[i][j] == '@')
{
edx = i;
edy = j;
}
}
}
return;
}