hdu 1885 Key Task(bfs+位运算)

题意:矩阵中'#'表示墙,'.'表示通路,要求从起点'*'到达终点'X',途中可能遇到一些门(大写字母),要想经过,必须有对应的钥匙(小写字母)。问能否完成,若能,花费的时间是多少。

分析:同hdu 1429,只不过这里用map把四种钥匙标号了,否则爆内存。

错误:判断门的条件用 isupper(ch) 表示,所以终点'X'也在这个范围内。

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<cctype>
  4 #include<map>
  5 #include<queue>
  6 #include<algorithm>
  7 using namespace std;
  8 
  9 const int MAXN=111;
 10 const int KEY=4;
 11 
 12 map<char,int> mp;
 13 
 14 
 15 int dir[4][2]={0,-1,0,1,-1,0,1,0};
 16 
 17 struct Node{
 18     int x,y,t,key;
 19     Node(){}
 20     Node(int _x,int _y,int _t,int _key):x(_x),y(_y),t(_t),key(_key){}
 21 };
 22 
 23 char g[MAXN][MAXN];
 24 int mark[MAXN][MAXN][1<<KEY];
 25 queue<Node>q;
 26 
 27 int n,m,T;
 28 
 29 bool wall(int x,int y)
 30 {
 31     if(x<0||x>=n||y<0||y>=m)
 32         return true;
 33     if(g[x][y]=='#')
 34         return true;
 35     return false;
 36 }
 37 
 38 int bfs(int sx,int sy)
 39 {
 40     while(!q.empty())
 41         q.pop();
 42 
 43     memset(mark,0,sizeof(mark));
 44     mark[sx][sy][0]=1;
 45     q.push(Node(sx,sy,0,0));
 46     while(!q.empty())
 47     {
 48         Node e=q.front();q.pop();
 49 
 50         for(int i=0;i<4;i++)
 51         {
 52             int dx=e.x+dir[i][0];
 53             int dy=e.y+dir[i][1];
 54             int dt=e.t+1;
 55             int dkey=e.key;
 56 
 57             char ch=g[dx][dy];
 58 
 59             if(wall(dx,dy))
 60                 continue;
 61             if(mark[dx][dy][dkey])
 62                 continue;
 63             if(g[dx][dy]=='X')
 64                 return dt;
 65             if(isupper(ch)&&!(dkey&(1<<mp[ch])))
 66                 continue;
 67             if(islower(ch))
 68                 dkey=dkey|(1<<mp[ch]);
 69 
 70             mark[dx][dy][dkey]=1;
 71             q.push(Node(dx,dy,dt,dkey));
 72         }
 73     }
 74     return -1;
 75 }
 76 
 77 int main()
 78 {
 79     mp['B']=mp['b']=0;
 80     mp['Y']=mp['y']=1;
 81     mp['R']=mp['r']=2;
 82     mp['G']=mp['g']=3;
 83     while(~scanf("%d%d",&n,&m))
 84     {
 85         if(!n&&!m)
 86             return 0;
 87 
 88         for(int i=0;i<n;i++)
 89             scanf("%s",g[i]);
 90 
 91         int sx,sy,ex,ey;
 92         for(int i=0;i<n;i++)
 93             for(int j=0;j<m;j++)
 94                 if(g[i][j]=='*'){
 95                     sx=i;
 96                     sy=j;
 97                     g[i][j]='.';
 98                 }
 99 
100         int ans=bfs(sx,sy);
101         if(ans==-1)
102             printf("The poor student is trapped!\n");
103         else
104             printf("Escape possible in %d steps.\n",ans);
105     }
106     return 0;
107 }
View Code

 

posted @ 2013-10-01 13:25  Thousand Sunny  阅读(219)  评论(0编辑  收藏  举报