poj 1475 推箱子

bfs是一层层的遍历下去,每多一层即为多走一步,因此只要遇到T就停,此时肯定是最小步数。

所以这两层bfs应为,先对箱子的最少步数进行bfs,从而求出推箱子所用最少步数;

然后箱子bfs内部嵌入人的bfs,从而箱子每走一步,判断一下这个移动能否由人来完成(由箱子的移动倒推人应该在的位置,看这个位置是否合理)。

一、http://tech.artyoo.me/?p=282

  1 #include <map>
  2 #include <set>
  3 #include <queue>
  4 #include <stack>
  5 #include <math.h>
  6 #include <time.h>
  7 #include <stdio.h>
  8 #include <stdlib.h>
  9 #include <iostream>
 10 #include <limits.h>
 11 #include <string.h>
 12 #include <string>
 13 #include <algorithm>
 14 #include <iomanip>
 15 #define read freopen("in.txt","r",stdin)
 16 #define write freopen("out.txt","w",stdout)
 17 using namespace std;
 18 #define MAXSIZE 22
 19 typedef struct {
 20     int bx, by, px, py;
 21     string path;
 22 } Node;
 23 typedef struct {
 24     int x, y;
 25     string path;
 26 } Point;
 27 int row, col;
 28 char grid[MAXSIZE][MAXSIZE];
 29 bool vis[MAXSIZE][MAXSIZE][4], vis2[MAXSIZE][MAXSIZE];
 30 Node st;
 31 int caseID;
 32 queue<Node> qb;
 33 queue<Point> qp;
 34
 35 const int dx[] = {-1, 1, 0, 0};
 36 const int dy[] = {0, 0, -1, 1};
 37 const char Dir[] = {‘N‘, ‘S‘, ‘W‘, ‘E‘};
 38 const char dir[] = {‘n‘, ‘s‘, ‘w‘, ‘e‘};
 39 string person_path;
 40
 41 int Min(int a,int b){return a<b?a:b;}
 42 int Max(int a,int b){return a>b?a:b;}
 43
 44 bool bfs_person(Point sp, Point ep, int bx, int by) {
 45     person_path = "";
 46     memset(vis2, false, sizeof(vis2));
 47     while(!qp.empty()) qp.pop();
 48     sp.path = "";
 49     qp.push(sp);
 50     vis2[sp.x][sp.y] = true;
 51     while(!qp.empty()) {
 52         Point now = qp.front(); qp.pop();
 53         if(now.x == ep.x && now.y == ep.y) {
 54             person_path = now.path;
 55             return true;
 56         }
 57         for(int d = 0; d < 4; d++) {
 58             int x = now.x + dx[d];
 59             int y = now.y + dy[d];
 60             if(x >= 0 && x < row && y >= 0 && y < col && grid[x][y] != ‘#‘ && !(x == bx && y == by)) {
 61                 if(!vis2[x][y]) {
 62                     Point next;
 63                     next.x = x;
 64                     next.y = y;
 65                     next.path = now.path + dir[d];
 66                     qp.push(next);
 67                     vis2[x][y] = true;
 68                 }
 69             }
 70         }
 71     }
 72     return false;
 73 }
 74
 75 string bfs_box() {
 76     memset(vis, false, sizeof(vis));
 77     while(!qb.empty()) qb.pop();
 78     qb.push(st);
 79     while(!qb.empty()) {
 80         Node now;
 81         now = qb.front(); qb.pop();
 82         if(grid[now.bx][now.by] == ‘T‘) {
 83             return now.path;
 84         }
 85         for(int d = 0; d < 4; d++) {
 86             int x = now.bx + dx[d];
 87             int y = now.by + dy[d];
 88             if(x >= 0 && x < row && y >= 0 && y < col && grid[x][y] != ‘#‘) {
 89                 if(!vis[x][y][d]) {
 90                     Point sp, ep; /* sp: 人的当前位置;ep:人要按当前方向推箱子的话必须得到达的位置 */
 91                     sp.x = now.px;  sp.y = now.py;
 92                     ep.x = now.bx;  ep.y = now.by;
 93                     switch(d) {
 94                         case 0: ep.x += 1; break;
 95                         case 1: ep.x -= 1; break;
 96                         case 2: ep.y += 1; break;
 97                         case 3: ep.y -= 1; break;
 98                     }
 99                     if(ep.x >= 0 && ep.x < row && ep.y >= 0 && ep.y < col && grid[ep.x][ep.y] != ‘#‘) {
100                         if(bfs_person(sp, ep, now.bx, now.by)) {
101                             Node next;
102                             next.bx = x;  next.by = y;
103                             next.px = now.bx;  next.py = now.by;
104                             next.path = now.path + person_path + Dir[d];
105                             qb.push(next);
106                             vis[x][y][d] = true;
107                         }
108                     }
109                 }
110             }
111         }
112     }
113     return "Impossible.";
114 }
115
116 int main() {
117     read; write;
118     caseID = 0;
119     while(scanf("%d%d", &row, &col) && row && col) {
120         getchar();
121         for(int i = 0; i < row; i++) {
122             gets(grid[i]);
123         }
124         for(int i = 0; i < row; i++) {
125             for(int j = 0; j < col; j++) {
126                 if(grid[i][j] == ‘B‘) {
127                     st.bx = i;
128                     st.by = j;
129                     grid[i][j] = ‘.‘;
130                 } else if(grid[i][j] == ‘S‘) {
131                     st.px = i;
132                     st.py = j;
133                     grid[i][j] = ‘.‘;
134                 }
135             }
136         }
137         st.path = "";
138         printf("Maze #%d\n", ++caseID);
139         cout << bfs_box() << endl << endl;
140     }
141     return 0;
142 }

二、http://www.cnblogs.com/Missa/archive/2012/10/07/2714435.html

  1 #include <iostream>
  2 #include <cstring>
  3 #include <cstdio>
  4 #include <algorithm>
  5 #include <queue>
  6 #include <string>
  7
  8 using namespace std;
  9
 10 #define MAXN 22
 11 char P[4] = { ‘N‘, ‘S‘, ‘W‘, ‘E‘ };
 12 char M[4] = { ‘n‘, ‘s‘, ‘w‘, ‘e‘ };
 13 int R, C;
 14 int dir[4][2] = { -1, 0, 1, 0, 0, -1, 0, 1 };//之前当成坐标轴里x,y坐标来算,怎么都不对。后来发现原来x,y是行数和列数。x-1代表到上一行去,即N。
 15 char map[MAXN][MAXN];
 16 struct point
 17 {
 18     int x, y;
 19     int p_x, p_y;//当前状态person所在的地方
 20     string ans;
 21 };
 22 bool isok(int x, int y)
 23 {
 24     if (x >= 0 && x < R && y >= 0 && y < C && map[x][y] != ‘#‘)
 25         return true;
 26     return false;
 27 }
 28 string tmp;
 29 bool bfs_person(point en, point cu)
 30 {
 31     tmp = "";
 32     point st;
 33     st.x = en.p_x;
 34     st.y = en.p_y;
 35     st.ans = "";
 36     queue<point>q;
 37     bool vis[MAXN][MAXN];
 38     memset(vis, 0, sizeof(vis));
 39     while (!q.empty())
 40         q.pop();
 41     q.push(st);
 42     while (!q.empty())
 43     {
 44         point cur, next;
 45         cur = q.front();
 46         q.pop();
 47         if (cur.x == en.x && cur.y == en.y)
 48         {
 49             tmp = cur.ans;
 50             return true;
 51         }
 52         for (int i = 0; i < 4; i++)
 53         {
 54             next = cur;
 55             next.x = cur.x + dir[i][0];
 56             next.y = cur.y + dir[i][1];
 57             if (!isok(next.x, next.y)) continue;
 58             if (next.x == cu.x && next.y == cu.y) continue;//cu.x,cu.y is the location of the box.
 59             if (vis[next.x][next.y]) continue;//来过的地方就不能在来了???????莫非bfs都是这样?
 60             vis[next.x][next.y] = 1;
 61             next.ans = cur.ans + M[i];
 62             //cout << "M[i] "<<M[i] << endl;
 63             //cout << "cur.ans " << cur.ans << endl;
 64             q.push(next);
 65         }
 66     }
 67     return false;
 68 }
 69 string bfs_box()
 70 {
 71     bool vis[MAXN][MAXN][4];//某点四个方向是否访问!!0==N,1==S,2==W,3==E
 72     point st;
 73     st.x = st.y = -1;
 74     st.p_x = st.p_y = -1;
 75     st.ans = "";
 76     for (int i = 0; i < R && (st.x == -1 || st.p_x == -1); i++)
 77     for (int j = 0; j < C && (st.x == -1 || st.p_x == -1); j++)
 78     if (map[i][j] == ‘B‘)
 79     {
 80         st.x = i;
 81         st.y = j;
 82         map[i][j] = ‘.‘;
 83     }
 84     else if (map[i][j] == ‘S‘)
 85     {
 86         st.p_x = i;
 87         st.p_y = j;
 88         map[i][j] = ‘.‘;
 89     }
 90     //----------------------------------------
 91     //cout<<"st.x="<<st.x<<" st.y="<<st.y<<" st.p_x="<<st.p_x<<" st.p_y="<<st.p_y<<endl;
 92     //----------------------------------------
 93     queue<point> q;
 94     while (!q.empty())
 95         q.pop();
 96     q.push(st);
 97     memset(vis, 0, sizeof(vis));
 98     while (!q.empty())
 99     {
100         point cur = q.front(); q.pop();
101         //----------------------------------------
102         //        cout<<"cur.x="<<cur.x<<" cur.y="<<cur.y<<" cur.p_x="<<cur.p_x<<" cur.p_y="<<cur.p_y<<endl;
103         //    cout<<"-----------------------------\n";
104         //----------------------------------------
105         point next, pre;
106         if (map[cur.x][cur.y] == ‘T‘)
107             return cur.ans;
108         for (int i = 0; i < 4; i++)
109         {
110             next = cur;
111             next.x = cur.x + dir[i][0];
112             next.y = cur.y + dir[i][1];
113             if (!isok(next.x, next.y))
114                 continue;
115             if (vis[next.x][next.y][i])
116                 continue;
117             pre = cur;
118             switch (i)
119             {
120             case 0: pre.x = cur.x + 1; break;
121             case 1: pre.x = cur.x - 1; break;
122             case 2: pre.y = cur.y + 1; break;
123             case 3: pre.y = cur.y - 1; break;
124             }
125             if (!bfs_person(pre, cur))//搜寻人是否能走到特定的位置
126                 continue;
127             vis[next.x][next.y][i] = 1;
128             next.ans = cur.ans + tmp;
129             next.ans = next.ans + P[i];
130             cout << "P[i] " << P[i] << endl;
131             cout <<"cur--"<< cur.x << "," << cur.y << ";" << cur.p_x << "," << cur.p_y << endl;
132             cout <<"next--" << next.x << "," << next.y << ";" << next.p_x << "," << next.p_y << endl;
133             next.p_x = cur.x; next.p_y = cur.y;
134             q.push(next);
135         }
136     }
137     return "Impossible.";
138 }
139
140 int main()
141 {
142     int cas = 1;
143     while (scanf("%d%d", &R, &C) && (R + C))
144     {
145         getchar();
146         for (int i = 0; i < R; i++)
147             gets(map[i]);
148
149         //---------------------------------------
150         //    for(int i=0;i<R;i++)
151         //    cout<<map[i]<<endl;
152         //----------------------------------------
153
154         printf("Maze #%d\n", cas++);
155         //printf("%s\n",bfs_box());
156         cout << bfs_box() << endl << endl;
157     }
158     return 0;
159 }
时间: 2024-10-14 08:17:19

poj 1475 推箱子的相关文章

poj 1254 推箱子

New~ 欢迎“热爱编程”的高考少年——报考杭州电子科技大学计算机学院 关于2015年杭电ACM暑期集训队的选拔 欢迎参加: 浙江杭电{安控杯}Hackthon 推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6027    Accepted Submission(s): 1721 Problem Description 推箱子

2016暑假集训补题系列——POJ 1475

POJ 1475 Pushing Boxes 题意:模拟推箱子游戏给出一个二维图,S表示人的位置,B表示箱子位置,T表示目标位置.要求最短输出路径大写字母代表推,小写字母代表走. 思路:BFS+BFS,首先对箱子进行BFS,每一次在加入新的节点时对人再进行一次BFS,找到他走到需要推箱子的地方的最小路径.(最开始不知道怎么记录路径,之前也几乎不用String,结果如此好用,还可以直接加...) #include<cstdio> #include<algorithm> #includ

hihoCoder_推箱子

一.题目 题目1 : 推箱子 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 推箱子是一款经典游戏.如图所示,灰色格子代表不能通过区域,蓝色方格是箱子,黑色圆形代表玩家,含有圆点的格子代表目标点. 规定以下规则: 1.一局游戏中只会有一个箱子,一个玩家和一个目标点. 2.通过方向键控制玩家移动. 3.图中的灰色格子代表墙壁,玩家与箱子都不能通过. 4.推到墙壁的箱子,就无法再将箱子推离墙壁,因为玩家无法到达箱子靠墙壁的一侧去推箱子.也就是说箱子只能以"被推"

致佳音: 推箱子游戏自动求解算法设计(一)

本来酷爱音乐, 老衲也想谱一曲<献给爱丽丝>之类, 通俗又有境界的曲子, 奈何没有那个水平, 也不是一个程序员做的勾当,于是就有了本文. 希望莲花妹妹跟着思路走,能遗忘那些太多的忧伤-- 本文分以下四个小节: 一.平面寻路算法(Alpha Star) 二.闭合图形填充算法(扫描线种子填充) 三.推箱子求解 四.执行效率的优化 日本人有个程序叫Sokuban Automatic Solver,文件名是sokoban722.exe我附带在资源里面 不过日本人的东西没有开源,我们也不知道它里面的花花

致佳音: 推箱子游戏自动求解算法设计(二)

这一个小节我们说一说传说中的A×算法,其实之前也上传过类似的小件件,这里我们就去剖析一下它 毕竟在游戏程序,我们要从一点移动到另一点,并得到最短路程的轨迹,类似这种算法还有好几种,执行效率都差不多,不过大多不能得到轨迹 首先,从一点移动到另一点,最快就是直接走过去了,就像小男生爱上小女生,最好的办法就是直接走到她面前说:我爱你 不过理想状态,几乎是没有的,弯路那是必然的经过,有曲线,其实更美-- 那么弯路该怎么走呢,是不是先去背景看下毛主席,再去三亚晒个太阳,再回来告诉她外面的世界好美,不,不,

12月28日 二维数组的应用:第一个小游戏(推箱子)

小游戏:******推箱子******** static void Main(string[] args) { int i, j; int[,] a = new int[10, 10]                  //二维数组的定义           类型[,] 数组名 = new  类型 [行数, 列数] {赋值}:   或单个赋值 a[i,j]=1; { {1,1,1,1,1,1,1,1,1,1}, {1,0,0,0,0,0,0,0,0,1}, {1,0,2,0,0,8,0,0,0,

搜索 [HDU 1254] 推箱子

推箱子 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5343    Accepted Submission(s): 1503 Problem Description 推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子

C语言版推箱子

推箱子源代码初步: 1 #include<stdio.h> 2 #include<conio.h> 3 #include<stdlib.h> 4 #define boolean int 5 #define true 1 6 #define false 0 7 8 #define ROWS 10 9 //之所以定义为11,是因为字符串的尾部的\0 10 #define COLUMNS 11 11 12 //根据程序定义或者文件读入来构建地图,然后把他绘制到屏幕上 13 v

java版 推箱子,俄罗斯方块,诗歌默写,坦克!由瑶哥特改造哦!

其实我发现自己用java还真的写了好多小游戏了,一起刚刚开始学java的时候听学长说,写个俄罗斯方块要看一本搬砖厚的书, 刚开始还不信,不过现在信了,javaSe学完是要有本搬砖候的书了! 这个好像也是大一写的吧,具体时间都记不得了. 这个游戏还是改良了一下咯,我添加了个魔鬼的角色在里面, 魔鬼可以退箱子,而且魔鬼不能碰到你,碰到你,你就over了 .比以前的推箱子好玩些.我自己也经常玩玩. 懒得把自己写的一些java写游戏一个一个发文章了一次性吧,总之如果要代码找我QQ就好了935090232