hdu1429 胜利大逃亡(续) (BFS+简单状态压缩)

来源:互联网 发布:成都家电维修软件 编辑:程序博客网 时间:2024/05/16 09:35

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1429

题目大意:逃离迷宫,但是迷宫里有钥匙和门

题目思路:

关于状态压缩:

 1.判断一个数字x二进制下第i位是不是等于1。

方法:if ( ( ( 1 << ( i - 1 ) ) & x ) > 0)

将1左移i-1位,相当于制造了一个只有第i位上是1,其他位上都是0的二进制数。然后与x做与运算,如果结果>0,说明x第i位上是1,反之则是0。

2.将一个数字x二进制下第i位更改成1。

方法:x = x | ( 1<<(i-1) )

证明方法与1类似,此处不再重复证明。

3.把一个数字二进制下最靠右的第一个1去掉。

方法:x=x&(x-1)

题目:

因为一共只有十把钥匙,所以含有的状态较小,故可以使用状态压缩的方法储存是否拿到钥匙,那么visit数组就变成了visit[x][y][状态],状态用二进制来表示,然后再用bfs进行处理就能较快速的完成这个问题。

代码:


#include <bits/stdc++.h>using namespace std;int n,m,t;char mmap[21][21];bool visit[21][21][2049];int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};int sx,sy,ex,ey;struct node{    int x,y,s;//s表示状态    int step;};queue<node>Q;int bfs(){    while(!Q.empty()) Q.pop();    memset(visit,0,sizeof(visit));    node a,now,next;    a.x=sx,a.y=sy,a.s=0,a.step=0;    visit[a.x][a.y][0]=1;    Q.push(a);    while(!Q.empty()){        now = Q.front(),Q.pop();        for(int i=0;i<4;i++){            next.x=now.x+dir[i][0];            next.y=now.y+dir[i][1];            next.s=now.s;            next.step=now.step+1;            if(next.x==ex&&next.y==ey) return next.step;            if(next.x<0||next.x>=n||next.y<0||next.y>=m) continue;            if(mmap[next.x][next.y]=='*') continue;            if(visit[next.x][next.y][next.s]) continue;            if(mmap[next.x][next.y]>='A'&&mmap[next.x][next.y]<='Z'){                int key=mmap[next.x][next.y]-'A'+1;                if((next.s>>(key-1))&1){                        Q.push(next);                        visit[next.x][next.y][next.s]=1;                }                else continue;            }            if(mmap[next.x][next.y]>='a'&&mmap[next.x][next.y]<='z'){                int nkey=mmap[next.x][next.y]-'a'+1;                next.s=(next.s|(1<<(nkey-1)));                if(!visit[next.x][next.y][next.s]){                    visit[next.x][next.y][next.s]=1;                    Q.push(next);                }                else continue;            }            if(mmap[next.x][next.y]=='.'){                if(!visit[next.x][next.y][next.s]){                    visit[next.x][next.y][next.s]=1;                    Q.push(next);                }                else continue;            }            if(mmap[next.x][next.y]=='@'){                if(!visit[next.x][next.y][next.s]){                    visit[next.x][next.y][next.s]=1;                    Q.push(next);                }                else continue;            }        }    }    return -1;}int main(){    while(~scanf("%d%d%d",&n,&m,&t)){        for(int i=0;i<n;i++){            getchar();            for(int j=0;j<m;j++){            scanf("%c",&mmap[i][j]);            if(mmap[i][j]=='@') sx=i,sy=j;            if(mmap[i][j]=='^') ex=i,ey=j;            }        }        printf("%d\n",bfs()<t?bfs():-1);        getchar();    }}


原创粉丝点击