Codeforces 225D Snake 位运算hash + bfs

题意:有一只在n*m(1<=n,m<=15)的迷宫内,蛇头为1,身长<=9,@为苹果,#为墙,问最小几步能吃到苹果。吃不到输出-1。

题解:hash存储两个相邻蛇身的关系上下左右四种状态用两位二进制表示,dis[ i ][ j ][ t ] 表示蛇头在i j 位置蛇身状态为 t 的时候的最小步数,然后bfs即可。


Sure原创,转载请注明出处。

#include <iostream>
#include <cstdio>
#include <memory.h>
#include <queue>
#define MAX(a , b) ((a) > (b) ? (a) : (b))
using namespace std;
const int maxn = 20;
const int maxt = 1 << 17;
const int move[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};
struct ddd
{
    int x,y,s;
};
char map[maxn][maxn];
int st[2][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[1][i-1] + move[j][1] == st[1][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][1];
        if(ppx == x && ppy == y) return false;
        st[0][0] = x;
        st[1][0] = y;
        st[0][1] = px;
        st[1][1] = py;
        for(int i=2;i<len;i++)
        {
            int d = ss & 3;
            px += move[d][0];
            py += move[d][1];
            if(px == x && py == y) return false;
            st[0][i] = px;
            st[1][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[1][tmp] = j;
                len = MAX(len , tmp+1);
            }
            if(map[i][j] == '@')
            {
                edx = i;
                edy = j;
            }
        }
    }
    return;
}

int bfs()
{
    while(!Q.empty()) Q.pop();
    int key = hash();
    vis[st[0][0]][st[1][0]][key] = true;
    dis[st[0][0]][st[1][0]][key] = 0;
    ddd cur,tmp;
    tmp.x = st[0][0];
    tmp.y = st[1][0];
    tmp.s = key;
    Q.push(tmp);
    while(!Q.empty())
    {
        cur = Q.front();
        Q.pop();
        if(cur.x == edx && cur.y == edy)
        {
            return dis[edx][edy][cur.s];
        }
        for(int i=0;i<4;i++)
        {
            int tx = cur.x + move[i][0];
            int ty = cur.y + move[i][1];
            if(judge(tx , ty , cur.x , cur.y , cur.s))
            {
                tmp.x = tx;
                tmp.y = ty;
                tmp.s = hash();
                if(vis[tx][ty][tmp.s] == false)
                {
                    vis[tx][ty][tmp.s] = true;
                    dis[tx][ty][tmp.s] = dis[cur.x][cur.y][cur.s] + 1;
                    Q.push(tmp);
                }
            }
        }
    }
    return -1;
}

int main()
{
    while(~scanf("%d %d",&m,&n))
    {
        read();
        printf("%d\n",bfs());
    }
    return 0;
}


你可能感兴趣的:(struct,存储)