题目链接

http://poj.org/problem?id=1475

题意

推箱子游戏。输入迷宫、箱子的位置、人的位置、目标位置,求人是否能把箱子推到目标位置,若能则输出推的最少的路径,如果有多条步数相同的推的最少的路径,则输出总步数(人走的步数+推箱子的步数)最少的那条路径;若不能把箱子推到目标位置,则输出Impossible.

思路

先求出箱子到目标位置的最短路径(bfs_box),在bfs1推箱子的过程中,根据推的方向和箱子的位置得到人的位置,再求得人到达这个位置的最短路(bfs_person)即可。

代码

 #include <iostream>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
using namespace std; struct Node
{
int br, bc; //box_row,box_col
int pr, pc; //person_row,person_col
string ans; Node() {}
Node(int br, int bc, int pr, int pc, string ans) :br(br), bc(bc), pr(pr), pc(pc), ans(ans) {}
}; const int N = ;
int m, n;
char maze[N][N];
int dir[][] = { {-, }, {, }, {, -}, {, } };
char push[] = { 'N', 'S', 'W', 'E' };
char walk[] = { 'n', 's', 'w', 'e' };
int br, bc;
int pr, pc;
int tr, tc; bool ok(int r, int c)
{
if (r >= && r < m && c >= && c < n && maze[r][c] != '#')
return true;
return false;
} string tmp;
bool bfs_person(int sr, int sc, int er, int ec, Node node)
{
tmp = "";
int visit[N][N];
memset(visit, , sizeof(visit));
queue<Node> q;
q.push(Node(-, -, sr, sc, ""));
visit[sr][sc] = ;
visit[node.br][node.bc] = ; //注意
while (!q.empty())
{
Node cur = q.front();
q.pop();
if (cur.pr == er && cur.pc == ec)
{
tmp = cur.ans;
return true;
}
for (int i = ; i < ; i++)
{
int nr = cur.pr + dir[i][];
int nc = cur.pc + dir[i][];
if (ok(nr, nc) && !visit[nr][nc])
{
visit[nr][nc] = ;
string ans = cur.ans + walk[i];
q.push(Node(-, -, nr, nc, ans));
}
}
}
return false;
} string bfs_box()
{
int visit[N][N];
memset(visit, , sizeof(visit));
queue<Node> q;
q.push(Node(br, bc, pr, pc, ""));
visit[br][bc] = ;
while (!q.empty())
{
Node cur = q.front();
q.pop();
if (cur.br == tr && cur.bc == tc)
return cur.ans;
for (int i = ; i < ; i++)
{
int nr = cur.br + dir[i][];
int nc = cur.bc + dir[i][];
int pre_r = cur.br - dir[i][];
int pre_c = cur.bc - dir[i][];
if (ok(nr, nc) && ok(pre_r, pre_c) && !visit[nr][nc])
{
if (bfs_person(cur.pr, cur.pc, pre_r, pre_c, cur))
{
visit[nr][nc] = ;
Node next;
next.br = nr;
next.bc = nc;
next.pr = cur.br;
next.pc = cur.bc;
next.ans = cur.ans + tmp + push[i];
q.push(next);
}
}
}
}
return "Impossible.";
} int main()
{
//freopen("poj1475.txt", "r", stdin);
int cnt = ;
while (cin >> m >> n && m)
{
for (int i = ; i < m; i++)
{
for (int j = ; j < n; j++)
{
cin >> maze[i][j];
if (maze[i][j] == 'S')
{
pr = i;
pc = j;
}
else if (maze[i][j] == 'B')
{
br = i;
bc = j;
}
else if (maze[i][j] == 'T')
{
tr = i;
tc = j;
}
}
}
printf("Maze #%d\n", ++cnt);
cout << bfs_box() << endl << endl;
}
return ;
}

最新文章

  1. Android压缩图片到100K以下并保持不失真的高效方法
  2. php PDO调用带有out参数的存储过程(原创)
  3. SSIS 项目部署模型
  4. 互联网的寒冬来了,BAT都不社招了
  5. 转:Selenium之CSS Selector定位详解
  6. 如何修改配置以修复ThinkPad 小红帽滚轮失效?
  7. yii-mail yii 发送邮件
  8. linux下python启动第三方程序,并控制关闭
  9. ExtJs自学教程(2):从DOM看EXTJS
  10. Linux命令行访问网页
  11. ASP.NET问题处理---targetFramwork=‘4.0’错误
  12. STL——increment/decrement/dereference操作符
  13. C#生成MD5码
  14. Python-待
  15. Java使用RabbitMQ之公平分发
  16. centos限制用户使用部分命令
  17. android studio 3.0 集成ijkplayer
  18. JS和Java正则表达式验证
  19. CTF-练习平台-Misc之 细心的大象
  20. 每个 case 语句的结尾不要忘了加 break,否则将导致多个分支重叠

热门文章

  1. HDU 6194 后缀数组
  2. 手脱EXE32Pack v1.39
  3. Qt每次运行都是重新编译问题
  4. BZOJ 2083 vector的巧用+二分
  5. Spring REST 异常处理
  6. HEXO与Github.io搭建个人博客
  7. 搭建Elasticsearch5.6.8 分布式集群
  8. c语言中使用自带的qsort(结构体排序)+ 快排
  9. 【LIbreOJ】#6256. 「CodePlus 2017 12 月赛」可做题1
  10. 天梯赛 L2-009 抢红包