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

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

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

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

 #include <map>
#include <set>
#include <queue>
#include <stack>
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <limits.h>
#include <string.h>
#include <string>
#include <algorithm>
#include <iomanip>
#define read freopen("in.txt","r",stdin)
#define write freopen("out.txt","w",stdout)
using namespace std;
#define MAXSIZE 22
typedef struct {
int bx, by, px, py;
string path;
} Node;
typedef struct {
int x, y;
string path;
} Point;
int row, col;
char grid[MAXSIZE][MAXSIZE];
bool vis[MAXSIZE][MAXSIZE][], vis2[MAXSIZE][MAXSIZE];
Node st;
int caseID;
queue<Node> qb;
queue<Point> qp; const int dx[] = {-, , , };
const int dy[] = {, , -, };
const char Dir[] = {'N', 'S', 'W', 'E'};
const char dir[] = {'n', 's', 'w', 'e'};
string person_path; int Min(int a,int b){return a<b?a:b;}
int Max(int a,int b){return a>b?a:b;} bool bfs_person(Point sp, Point ep, int bx, int by) {
person_path = "";
memset(vis2, false, sizeof(vis2));
while(!qp.empty()) qp.pop();
sp.path = "";
qp.push(sp);
vis2[sp.x][sp.y] = true;
while(!qp.empty()) {
Point now = qp.front(); qp.pop();
if(now.x == ep.x && now.y == ep.y) {
person_path = now.path;
return true;
}
for(int d = ; d < ; d++) {
int x = now.x + dx[d];
int y = now.y + dy[d];
if(x >= && x < row && y >= && y < col && grid[x][y] != '#' && !(x == bx && y == by)) {
if(!vis2[x][y]) {
Point next;
next.x = x;
next.y = y;
next.path = now.path + dir[d];
qp.push(next);
vis2[x][y] = true;
}
}
}
}
return false;
} string bfs_box() {
memset(vis, false, sizeof(vis));
while(!qb.empty()) qb.pop();
qb.push(st);
while(!qb.empty()) {
Node now;
now = qb.front(); qb.pop();
if(grid[now.bx][now.by] == 'T') {
return now.path;
}
for(int d = ; d < ; d++) {
int x = now.bx + dx[d];
int y = now.by + dy[d];
if(x >= && x < row && y >= && y < col && grid[x][y] != '#') {
if(!vis[x][y][d]) {
Point sp, ep; /* sp: 人的当前位置;ep:人要按当前方向推箱子的话必须得到达的位置 */
sp.x = now.px; sp.y = now.py;
ep.x = now.bx; ep.y = now.by;
switch(d) {
case : ep.x += ; break;
case : ep.x -= ; break;
case : ep.y += ; break;
case : ep.y -= ; break;
}
if(ep.x >= && ep.x < row && ep.y >= && ep.y < col && grid[ep.x][ep.y] != '#') {
if(bfs_person(sp, ep, now.bx, now.by)) {
Node next;
next.bx = x; next.by = y;
next.px = now.bx; next.py = now.by;
next.path = now.path + person_path + Dir[d];
qb.push(next);
vis[x][y][d] = true;
}
}
}
}
}
}
return "Impossible.";
} int main() {
read; write;
caseID = ;
while(scanf("%d%d", &row, &col) && row && col) {
getchar();
for(int i = ; i < row; i++) {
gets(grid[i]);
}
for(int i = ; i < row; i++) {
for(int j = ; j < col; j++) {
if(grid[i][j] == 'B') {
st.bx = i;
st.by = j;
grid[i][j] = '.';
} else if(grid[i][j] == 'S') {
st.px = i;
st.py = j;
grid[i][j] = '.';
}
}
}
st.path = "";
printf("Maze #%d\n", ++caseID);
cout << bfs_box() << endl << endl;
}
return ;
}

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

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <string> using namespace std; #define MAXN 22
char P[] = { 'N', 'S', 'W', 'E' };
char M[] = { 'n', 's', 'w', 'e' };
int R, C;
int dir[][] = { -, , , , , -, , };//之前当成坐标轴里x,y坐标来算,怎么都不对。后来发现原来x,y是行数和列数。x-1代表到上一行去,即N。
char map[MAXN][MAXN];
struct point
{
int x, y;
int p_x, p_y;//当前状态person所在的地方
string ans;
};
bool isok(int x, int y)
{
if (x >= && x < R && y >= && y < C && map[x][y] != '#')
return true;
return false;
}
string tmp;
bool bfs_person(point en, point cu)
{
tmp = "";
point st;
st.x = en.p_x;
st.y = en.p_y;
st.ans = "";
queue<point>q;
bool vis[MAXN][MAXN];
memset(vis, , sizeof(vis));
while (!q.empty())
q.pop();
q.push(st);
while (!q.empty())
{
point cur, next;
cur = q.front();
q.pop();
if (cur.x == en.x && cur.y == en.y)
{
tmp = cur.ans;
return true;
}
for (int i = ; i < ; i++)
{
next = cur;
next.x = cur.x + dir[i][];
next.y = cur.y + dir[i][];
if (!isok(next.x, next.y)) continue;
if (next.x == cu.x && next.y == cu.y) continue;//cu.x,cu.y is the location of the box.
if (vis[next.x][next.y]) continue;//来过的地方就不能在来了???????莫非bfs都是这样?
vis[next.x][next.y] = ;
next.ans = cur.ans + M[i];
//cout << "M[i] "<<M[i] << endl;
//cout << "cur.ans " << cur.ans << endl;
q.push(next);
}
}
return false;
}
string bfs_box()
{
bool vis[MAXN][MAXN][];//某点四个方向是否访问!!0==N,1==S,2==W,3==E
point st;
st.x = st.y = -;
st.p_x = st.p_y = -;
st.ans = "";
for (int i = ; i < R && (st.x == - || st.p_x == -); i++)
for (int j = ; j < C && (st.x == - || st.p_x == -); j++)
if (map[i][j] == 'B')
{
st.x = i;
st.y = j;
map[i][j] = '.';
}
else if (map[i][j] == 'S')
{
st.p_x = i;
st.p_y = j;
map[i][j] = '.';
}
//----------------------------------------
//cout<<"st.x="<<st.x<<" st.y="<<st.y<<" st.p_x="<<st.p_x<<" st.p_y="<<st.p_y<<endl;
//----------------------------------------
queue<point> q;
while (!q.empty())
q.pop();
q.push(st);
memset(vis, , sizeof(vis));
while (!q.empty())
{
point cur = q.front(); q.pop();
//----------------------------------------
// cout<<"cur.x="<<cur.x<<" cur.y="<<cur.y<<" cur.p_x="<<cur.p_x<<" cur.p_y="<<cur.p_y<<endl;
// cout<<"-----------------------------\n";
//----------------------------------------
point next, pre;
if (map[cur.x][cur.y] == 'T')
return cur.ans;
for (int i = ; i < ; i++)
{
next = cur;
next.x = cur.x + dir[i][];
next.y = cur.y + dir[i][];
if (!isok(next.x, next.y))
continue;
if (vis[next.x][next.y][i])
continue;
pre = cur;
switch (i)
{
case : pre.x = cur.x + ; break;
case : pre.x = cur.x - ; break;
case : pre.y = cur.y + ; break;
case : pre.y = cur.y - ; break;
}
if (!bfs_person(pre, cur))//搜寻人是否能走到特定的位置
continue;
vis[next.x][next.y][i] = ;
next.ans = cur.ans + tmp;
next.ans = next.ans + P[i];
cout << "P[i] " << P[i] << endl;
cout <<"cur--"<< cur.x << "," << cur.y << ";" << cur.p_x << "," << cur.p_y << endl;
cout <<"next--" << next.x << "," << next.y << ";" << next.p_x << "," << next.p_y << endl;
next.p_x = cur.x; next.p_y = cur.y;
q.push(next);
}
}
return "Impossible.";
} int main()
{
int cas = ;
while (scanf("%d%d", &R, &C) && (R + C))
{
getchar();
for (int i = ; i < R; i++)
gets(map[i]); //---------------------------------------
// for(int i=0;i<R;i++)
// cout<<map[i]<<endl;
//---------------------------------------- printf("Maze #%d\n", cas++);
//printf("%s\n",bfs_box());
cout << bfs_box() << endl << endl;
}
return ;
}

poj 1475 推箱子的更多相关文章

  1. POJ 1475 推箱

    推箱 时限:n.2000MS   内存限制:n.131072K 提交材料共计: 6600   接受: 2263   特别法官 描述 想象一下你站在一个二维迷宫里,由方形细胞组成,它们可能或可能不会充满 ...

  2. POJ1475 推箱子---模块化思想

    自古逢秋悲寂寥,我言秋日胜春朝. 晴空一鹤排云上,便引诗情到碧霄. --刘禹锡 题目:推箱子 网址:http://poj.org/problem?id=1475 推箱子游戏相信大家都不陌生,在本题中, ...

  3. POJ 3009:Curling 2.0 推箱子

    Curling 2.0 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 14090   Accepted: 5887 Desc ...

  4. poj 1475 || zoj 249 Pushing Boxes

    http://poj.org/problem?id=1475 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=249 Pushin ...

  5. POJ 1475 Pushing Boxes 搜索- 两重BFS

    题目地址: http://poj.org/problem?id=1475 两重BFS就行了,第一重是搜索箱子,第二重搜索人能不能到达推箱子的地方. AC代码: #include <iostrea ...

  6. OC推箱子

    #include<stdio.h> #include<stdlib.h> int main(void) { char sr;//存储用户输入的指令 //绘制地图 char a[ ...

  7. c语言游戏推箱子

    前两天做了推箱子小游戏,看似简单的一个小游戏背后却 有巨大的秘密,这秘密就是一大堆逻辑. 自从学习了函数过后,的确是解决了很多问题,而且调用很方便,尽管我现在都不是很会调用. 写完一个函数,准备测试一 ...

  8. JavaScript写一个小乌龟推箱子游戏

    推箱子游戏是老游戏了, 网上有各种各样的版本, 说下推箱子游戏的简单实现,以及我找到的一些参考视频和实例: 推箱子游戏的在线DEMO : 打开 如下是效果图: 这个拖箱子游戏做了移动端的适配, 我使用 ...

  9. 用C#制作推箱子小游戏

    思路分析: 一.制作一个地图 二.地图中放置墙.箱子.人.目标等 三.让小人动起来完成推箱子动作 游戏制作: 1.按照上述地图制作一个地图  (12行×13列) 地图可以看做是行和列组成的,即可以看做 ...

随机推荐

  1. Win10 VS2015 静态编译Qt5.6.2源码

    由于VS2015需要CRT等拓展组件,因此把内部编写的工具软件以静态发布,固需要编译Qt源码.Qt5.6.2版本,VS2015,Win10 1.安装python,perl,下载jom 2.改文件com ...

  2. SpringBoot集成WebSocket【基于STOMP协议】进行点对点[一对一]和广播[一对多]实时推送

    原文详细地址,有点对点,还有广播的推送:https://blog.csdn.net/ouyzc/article/details/79884688 下面是自己处理的一些小bug 参考原文demo,结合工 ...

  3. Java jstl标签使用总结

    1.在jsp文件中引用 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %&g ...

  4. MYSQL数据库的参数文件

    参数文件:告诉MySQL实例启动时在哪里可以找到数据库文件,并且指定某些初始化参数,这些参数定义了某种内存结构的大小等设置,还会介绍各种参数的类型. 参数文件 当MySQL实例启动时,MySQL会先去 ...

  5. Python制作回合制手游外挂简单教程(下)

    引入: 接着上篇的博文,今天我们讲如何实现助人为乐 前期准备: 如何获取图片中指定文字的坐标? 我的思路是截取一个小区域,再根据小区域左上角的坐标获取中央坐标 例如: 获取坐上角的x和y坐标,测量x到 ...

  6. SQL Server 导入excel时“该值违反了该列的完整性约束”错误

    SQL Server 导入excel时“该值违反了该列的完整性约束”错误 这个问题看似高大上,仔细分析了一下,ID列怎么会有重复呢? 原来是有很多空行呀!!! 所以导入excel时一定要注意空行的问题 ...

  7. Office 卸载问题(安装包的语言不受系统支持)

    本人系统Win7 这个问题搞了一下午.各种网站找解决办法.下载下来的都是一些垃圾软件. Win7以上调成兼容模式运行理论可行. 放上微软的解决方法: * 彻底卸载Office 2003: http:/ ...

  8. [javaSE] 基本数据类型对象包装类

    按照java面向对象的原则,每个基本类型都有对应的包装类 byte Byte short Short int Integer long Long boolean Boolean float Float ...

  9. 【SSH网上商城项目实战18】过滤器实现购物登录功能的判断

    转自:https://blog.csdn.net/eson_15/article/details/51425010 上一节我们做完了购物车的基本操作,但是有个问题是:当用户点击结算时,我们应该做一个登 ...

  10. 基于easyUI实现登录界面

    此文章是基于 EasyUI+Knockout实现经典表单的查看.编辑 一. 准备工作 1. 点击此下载相关文件,并把文件放到 ims 工程对应的文件夹下 二. 相关文件介绍 1. login.jsp: ...