题目链接

题意 : 出口不止一个,一共有四种颜色不同的门由大写字母表示,而钥匙则是对应的小写字母,当你走到门前边的位置时,如果你已经走过相应的钥匙的位置这个门就可以走,只要获得一把钥匙就可以开所有同颜色的门。问你能不能走出来。

思路 : 这个题比赛的时候完全没有思路,想了好久脑子都疼了也没想出来。原来是一个三维的BFS,因为要拿钥匙的缘故可能有些地方要来回走,所以不能像以前标记二维一样只要走过的点就不能走了,这里用三维来标记,你要是走过这个地方并且钥匙数都是一样的,那就不用再走了,因为那代表你又走回来了,看了网上大神写的学到了一个新的表示钥匙的方法,按位与,要不就要用数组什么的太麻烦。

  1 //HDU 1885
  2 #include <stdio.h>
  3 #include <string.h>
  4 #include <queue>
  5 #include <string>
  6 #include <iostream>
  7 
  8 using namespace std ;
  9 
 10 struct node
 11 {
 12     int x,y,step ;
 13     int keys ;
 14 } p[110],temp,temp1 ;
 15 
 16 int n,m ;
 17 int key[4] = {'b','y','r','g'} ;
 18 int door[4] = {'B','Y','R','G'} ;
 19 int dir[4][2] = {{0,-1},{0,1},{-1,0},{1,0}} ;
 20 bool vis[110][110][(1 << 4) + 10] ;
 21 char mapp[110][110] ;
 22 
 23 
 24 void BFS(int sx,int sy)
 25 {
 26     queue<node>Q ;
 27     temp.x = sx ;
 28     temp.y = sy ;
 29     temp.step = temp.keys = 0 ;
 30     Q.push(temp) ;
 31     vis[sx][sy][0] = true ;
 32     while(!Q.empty())
 33     {
 34         temp = Q.front() ;
 35         Q.pop() ;
 36         if(mapp[temp.x][temp.y] == 'X')
 37         {
 38             printf("Escape possible in %d steps.\n",temp.step) ;
 39             return ;
 40         }
 41         for(int i = 0 ; i < 4 ; i++)
 42         {
 43             temp1.x = temp.x + dir[i][0] ;
 44             temp1.y = temp.y + dir[i][1] ;
 45             temp1.step = temp.step+1;
 46             temp1.keys = temp.keys ;
 47 
 48             if(mapp[temp1.x][temp1.y] == '#' || temp1.x < 0 || temp1.x >= n || temp1.y < 0 || temp1.y >= m)
 49                 continue ;
 50             else if(islower(mapp[temp1.x][temp1.y]))
 51             {
 52                 for(int k = 0 ; k < 4 ; k++)
 53                 {
 54                     if(mapp[temp1.x][temp1.y] == key[k])
 55                     {
 56                         if((temp1.keys & (1 << k)) == 0)//如果这把钥匙没有,就加上。
 57                             temp1.keys += (1 << k) ;
 58 
 59                     }
 60                     if(!vis[temp1.x][temp1.y][temp1.keys])
 61                     {
 62                         Q.push(temp1) ;
 63                         vis[temp1.x][temp1.y][temp1.keys] = true ;
 64                         //break ;
 65                     }
 66                 }
 67             }
 68             else if(isupper(mapp[temp1.x][temp1.y]) && mapp[temp1.x][temp1.y] != 'X')
 69             {
 70                 for(int k = 0 ; k < 4 ; k++)
 71                 {
 72                     if(mapp[temp1.x][temp1.y] == door[k])
 73                     {
 74                         if(temp1.keys & (1 << k))
 75                         {
 76                             if(!vis[temp1.x][temp1.y][temp1.keys])
 77                             {
 78                                 vis[temp1.x][temp1.y][temp1.keys] = true ;
 79                                 Q.push(temp1) ;
 80 
 81                             }
 82                             break ;
 83                         }
 84                     }
 85                 }
 86             }
 87             else
 88             {
 89                 if(!vis[temp1.x][temp1.y][temp1.keys])
 90                 {
 91                     vis[temp1.x][temp1.y][temp1.keys] = true ;
 92                     Q.push(temp1) ;
 93                 }
 94             }
 95         }
 96     }
 97     printf("The poor student is trapped!\n") ;
 98 }
 99 
100 int main()
101 {
102     int sx,sy ;
103     while(~scanf("%d %d",&n,&m))
104     {
105         if(n == 0 && m == 0) break ;
106         for(int i = 0 ; i < n ; i++)
107             scanf("%s",mapp[i]) ;
108         memset(vis,false,sizeof(vis)) ;
109         for(int i = 0 ; i < n ; i++)
110         {
111             for(int j = 0 ; j < m ; j++)
112             {
113                 if(mapp[i][j] == '*')
114                 {
115                     sx = i ;
116                     sy = j ;
117                 }
118             }
119         }
120         BFS(sx,sy) ;
121     }
122     return 0 ;
123 }
View Code

 

posted on 2014-04-20 15:19  枫、  阅读(298)  评论(0编辑  收藏  举报