标签:
胜利大逃亡(续)-1
一共有10把钥匙,共计2^10种可能,搜索的状态除了点的坐标外,还有到达该点时的钥匙状况,由于2^10 比较小,可以用位运算表示钥匙的集合情况
对于集合S,判断一个数是否在集合里是 if(s>>i&1)
对集合S添加元素是:s|=1<<i
#include<cstdio> #include<cstring> #include<queue> using namespace std; #define cl(a,b) memset(a,b,sizeof(a)) const int maxn=22; const int inf=9999999; int n,m,t; char a[maxn][maxn]; int vis[1025][maxn][maxn]; int si,sj,ei,ej; int dir[][2]={{0,1},{1,0},{0,-1},{-1,0}}; struct node{ int x,y; int cnt; int time; node(int a,int b,int c,int d){ x=a;y=b;cnt=c;time=d; } }; bool pan(node s){ if(s.x<0||s.x>=n||s.y<0||s.y>=m||a[s.x][s.y]=='*') return false; return true; } int bfs(){ queue<node> q; cl(vis,false); q.push(node(si,sj,0,0)); vis[0][si][sj]=true; while(!q.empty()){ node s=q.front();q.pop(); if(s.time>=t-1)return -1; for(int i=0;i<4;i++){ node tmp=s; tmp.x+=dir[i][0]; tmp.y+=dir[i][1]; tmp.time++; if(pan(tmp)){ if(a[tmp.x][tmp.y]=='^'){ return tmp.time; } if((a[tmp.x][tmp.y]=='.'||a[tmp.x][tmp.y]=='@')&&!vis[tmp.cnt][tmp.x][tmp.y]){ q.push(tmp); vis[tmp.cnt][tmp.x][tmp.y]=true; } else if(a[tmp.x][tmp.y]>='a'&&a[tmp.x][tmp.y]<='j'){ tmp.cnt|=1<<(a[tmp.x][tmp.y]-'a');//添加钥匙 if(!vis[tmp.cnt][tmp.x][tmp.y]){ q.push(tmp); vis[tmp.cnt][tmp.x][tmp.y]=true; } } else if(a[tmp.x][tmp.y]>='A'&&a[tmp.x][tmp.y]<='J'&&!vis[tmp.cnt][tmp.x][tmp.y]){ if(tmp.cnt>>(a[tmp.x][tmp.y]-'A')&1){//判断是否有钥匙开门 q.push(tmp); vis[tmp.cnt][tmp.x][tmp.y]=true; } } } } } return -1; } int main(){ while(~scanf("%d%d%d",&n,&m,&t)){ for(int i=0;i<n;i++){ scanf("%s",a[i]); for(int j=0;j<m;j++){ if(a[i][j]=='@'){ si=i;sj=j; } if(a[i][j]=='^'){ ei=i;ej=j; } } } printf("%d\n",bfs()); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/u013167299/article/details/47166561