hdu 1044 Collect More Jewels

题意:

  一个n*m的迷宫,在t时刻后就会坍塌,问:在逃出来的前提下,能带出来多少价值的宝藏。

其中:

  ’*‘:代表墙壁;

  '.':代表道路;

  '@':代表起始位置;

  '<':代表出口;

  'A'~'J':代表宝藏;

解题思路:

  本题有两种思路:1,bfs+状态压缩;相比之下耗时多;

          2,bfs+dfs;耗时较少;

在这里着重介绍第一种方法:(博主也是现学现卖啦^_^)

  因为宝藏的数目比较少,所以我们可以对宝藏进行状态压缩(用二进制表示宝藏是否已经拾取,1表示已拾取,0表示未拾取),

  标记数组vis[i][x][y],i就是宝藏的拾取状态,(x,y)是当前搜索位置;(当然知道这些也不一定能ac)。

注意:(想要把题目ac的看过来)

  1:不可能输出“Impossible”。

  2:题目中的数据问题,题目的例子相当于有一个围墙,而可能数据并不总是如此。

  3:首先是如何判断当前的路径是否应该结束(并不是到‘<’为止,因为可能还有时间到达其他的宝藏)。

下面就祝大家ac愉快啦

代码:

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <queue>
  4 #include <iostream>
  5 #include <algorithm>
  6 using namespace std;
  7 #define N 55
  8 
  9 struct node
 10 {
 11     int x, y, z, t, val;
 12 };
 13 
 14 int n, m, t, num;
 15 int vis[1<<11][N][N], va[15], dir[4][2] = {1,0, -1,0, 0,1, 0,-1};
 16 char map[N][N];
 17 
 18 int bfs (int sx, int sy)
 19 {
 20     int num = -1;
 21 
 22     queue<node>Q;
 23     node cur, next;
 24 
 25     cur.x = sx, cur.y = sy;
 26     cur.val = cur.t = cur.z = 0;
 27     memset (vis, 0, sizeof(vis));
 28     vis[0][sx][sy] = 1;
 29 
 30     Q.push(cur);
 31     while (!Q.empty())
 32     {
 33         cur = Q.front();
 34         Q.pop();
 35         
 36         if (map[cur.x][cur.y] == '<')
 37         {
 38             if (cur.val > num)
 39                 num = cur.val;
 40         }
 41         if (cur.t > t)
 42             return num;
 43         for (int i=0; i<4; i++)
 44         {
 45             next.x = cur.x + dir[i][0];
 46             next.y = cur.y + dir[i][1];
 47             next.z = cur.z;
 48             next.val = cur.val;
 49             
 50             if (next.x<m && next.x>=0 && next.y<n && next.y>=0)
 51             {
 52                 next.t = cur.t + 1;
 53                 if (map[next.x][next.y] >= 'A' && map[next.x][next.y] <= 'Z')
 54                 {
 55                     int l = map[next.x][next.y] - 'A';
 56                     if ( !((1<<l) & next.z) )
 57                     {
 58                         next.val += va[l];
 59                         next.z = (1<<l) | next.z;
 60                     }
 61                 }
 62                 if (!vis[next.z][next.x][next.y] && map[next.x][next.y] != '*')
 63                     Q.push(next), vis[next.z][next.x][next.y] = 1;
 64             }
 65         }
 66     }
 67     return num;
 68 }
 69 int main ()
 70 {
 71     int c, i, j, s, l = 0, sx, sy;
 72     
 73     scanf ("%d", &c);
 74     
 75     while (c --)
 76     {
 77         scanf ("%d %d %d %d", &n, &m, &t, &s);
 78         
 79         for (i=0; i<s; i++)
 80             scanf ("%d", &va[i]);
 81         
 82         for (i=0; i<m; i++)
 83         {
 84             scanf ("%s", map[i]);
 85             for (j=0; j<n; j++)
 86                 if (map[i][j] == '@')
 87                     sx = i, sy = j;
 88         }
 89        
 90         num = bfs (sx, sy);
 91         if (l)
 92             printf ("\n");
 93         if (num != -1)
 94             printf ("Case %d:\nThe best score is %d.\n", ++l, num);
 95         else
 96             printf ("Case %d:\nImpossible\n", ++l, num);
 97     }
 98     
 99     return 0;
100 }

 

posted @ 2014-11-14 12:34  罗茜  阅读(187)  评论(0编辑  收藏  举报