当前位置:编程学习 > C/C++ >>

Codeforces 225D Snake 位运算hash + bfs

题意:有一只在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[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][t

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,