UVa 589 - Pushing Boxes

来源:互联网 发布:数据挖掘在的应用 编辑:程序博客网 时间:2024/06/05 13:26

题目:二维推箱子游戏,给你箱子、人和目标的位置,输出问题的解(推箱子和行走的路径)。

分析:搜索、优先队列。优先顺序为:首先保证推箱子的字数最少、然后是走的步数最少。

            利用二叉堆做优先队列,在上面进行bfs即可。

           

            搜索状态为:木块坐标+人的坐标,即一个四元组S(X,Y,x,y);

            每次(x,y)可以转化成周围四格位置,如果此时箱子在人的旁边,箱子能被推动,两者同向移动。

说明:注意搜索时按照字典序方向枚举,不然会WA╮(╯▽╰)╭。

#include <algorithm>#include <iostream>#include <cstdlib>#include <cstring>#include <cstdio>#include <cmath>using namespace std;char maps[20][21];typedef struct node0{int  X,Y,x,y;int  front,push,move,id;char step;}dnode;dnode H[160001];dnode Q[160001];bool  U[20][20][20][20];int   dxy[4][2] = {0,1,-1,0,1,0,0,-1};char  O[5] = "ENSW",o[5] = "ensw";int   q_size;//banery_heap defineint bh_size; void bh_init(){bh_size = 0;}int bh_empty(){return bh_size == 0;}bool bh_cmp(dnode a, dnode b){if (a.push != b.push)return a.push < b.push;return a.move < b.move;}void bh_insert(dnode s){H[++ bh_size] = s;int now = bh_size;while (now > 1 && bh_cmp(H[now], H[now>>1])) {swap(H[now], H[now>>1]);now = now>>1;}}dnode bh_delete(void){swap(H[bh_size], H[1]);int now = 1;while (1) {int New = now,L = (now<<1),R = (now<<1)+1;if (L < bh_size && bh_cmp(H[L], H[New])) New = L;if (R < bh_size && bh_cmp(H[R], H[New])) New = R;if (now == New) break;swap(H[now], H[New]);now = New;}return H[bh_size --];}//banery_heap endvoid output(dnode s){if (s.front) {output(Q[s.front]);printf("%c",s.step);}else printf("%c",s.step);}void bfs(dnode s, int n, int m){memset(U, 0, sizeof(U));U[s.X][s.Y][s.x][s.y] = 1;q_size = 0;bh_init();bh_insert(s);while (!bh_empty()) {dnode New,now = bh_delete();Q[q_size ++] = now;for (int k = 0 ; k < 4 ; ++ k) {New = now;New.x += dxy[k][0];New.y += dxy[k][1];New.front = q_size-1;if (New.x < 0 || New.x >= n || New.y < 0 || New.y >= m)continue;//推箱子 if (New.X == New.x && New.Y == New.y) {New.X += dxy[k][0];New.Y += dxy[k][1];if (New.X < 0 || New.X >= n || New.Y < 0 || New.Y >= m)continue;if (maps[New.X][New.Y] != '#' && !U[New.X][New.Y][New.x][New.y]) {New.step = O[k];New.push ++;if (maps[New.X][New.Y] == 'T') {output(New);return;}U[New.X][New.Y][New.x][New.y] = 1;bh_insert(New);}}else if (maps[New.x][New.y] != '#' && !U[New.X][New.Y][New.x][New.y]) {New.step = o[k];New.move ++;U[New.X][New.Y][New.x][New.y] = 1;bh_insert(New);}}}printf("Impossible.");}int main(){int n,m,t = 1;while (~scanf("%d%d",&n,&m) && n && m) {for (int i = 0 ; i < n ; ++ i)scanf("%s",maps[i]);dnode s;for (int i = 0 ; i < n ; ++ i)for (int j = 0 ; j < m ; ++ j) {if (maps[i][j] == 'S') {s.x = i; s.y = j;}if (maps[i][j] == 'B') {s.X = i; s.Y = j;}}printf("Maze #%d\n",t ++);bfs(s, n, m);printf("\n\n");}    return 0;}


0 0
原创粉丝点击