题意:
一个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 #include2 #include 3 #include 4 #include 5 #include 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 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 =0 && 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<