POJ1475【推箱子】(双bfs)
先对箱子bfs,箱子想要推到那个位置,我们人就必须移动到箱子的后面去推它,因此每次推箱子,需要再对人bfs来判断人能不能走到推箱子需要的地方以及最少的步数,
struct rec { int bx, by, px, py;//箱子的坐标 人的坐标 string path;//保存路径 rec(int _bx = 0, int _by = 0, int _px = 0, int _py = 0, string _path = "") :bx(_bx), by(_by), px(_px), py(_py), path(_path){} };
int bbx = cur.bx + dx[i];
int bby = cur.by + dy[i];
int ppx = cur.bx - dx[i];
int ppy = cur.by - dy[i];
bbx,bby就是箱子要推到的位置,ppx,ppy就是人推箱子需要走到的地方,cur.px,cur.py是当前人所在的地方,我们需要再进行一次bfs来判断能不能从当前位置走到目标位置,并且保存路径
能走到目标位置我们就把新状态的箱子加入队列,继续对箱子bfs
#include<bits/stdc++.h> using namespace std; struct rec { int bx, by, px, py; string path; rec(int _bx = 0, int _by = 0, int _px = 0, int _py = 0, string _path = "") :bx(_bx), by(_by), px(_px), py(_py), path(_path){} }; struct person{ int px, py; string path; person(int _px = 0, int _py = 0, string _path = ""):px(_px), py(_py), path(_path){} }; char p[5] = { 'n', 's', 'e', 'w' }; char b[5] = { 'N', 'S', 'E', 'W' }; int dx[4] = { -1, 1, 0, 0 }, dy[4] = { 0, 0, 1, -1 }; char maze[25][25]; int n,m; rec st; int cas; void parse() { for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { if (maze[i][j] == 'S') { st.px = i, st.py = j; } else if (maze[i][j] == 'B') { st.bx = i, st.by = j; } } } } bool valid(int x, int y) { if (x < 0 || x >= n || y < 0 || y >= m) return false; if (maze[x][y] == '#') return false; return true; } bool bfs1(int sx,int sy,int gx,int gy,int bbx,int bby,string &path)//判断能否从当前人在的位置(sx,sy)走到推箱子所需的位置(gx,gy); (bbx,bby)是当前箱子的位置 { int vis[25][25]; memset(vis, 0, sizeof(vis)); vis[sx][sy] = 1; vis[bbx][bby] = 1; queue<person> q; person f; f.px = sx, f.py = sy, f.path = ""; q.push(f); while (!q.empty()) { person cur = q.front(); q.pop(); if (cur.px == gx&&cur.py == gy) { path = cur.path; return true; } for (int i = 0; i < 4; i++) { int nx = cur.px + dx[i], ny = cur.py + dy[i]; if (valid(nx, ny) && !vis[nx][ny]) { vis[nx][ny] = 1; person nxt; nxt.px = nx; nxt.py = ny; nxt.path = cur.path + p[i]; q.push(nxt); } } } return false; } string bfs() { string ans; int flag = 0; int vis[25][25]; memset(vis, 0, sizeof(vis)); queue<rec> que; vis[st.bx][st.by] = 1; st.path = ""; que.push(st); while (!que.empty()) { rec cur = que.front(); que.pop(); for (int i = 0; i < 4; i++) { int bbx = cur.bx + dx[i], bby = cur.by + dy[i]; int ppx = cur.bx - dx[i], ppy = cur.by - dy[i]; string path = ""; if (valid(bbx, bby) && valid(ppx, ppy) && !vis[bbx][bby]) { if (bfs1(cur.px, cur.py, ppx, ppy, cur.bx, cur.by, path)) { vis[bbx][bby] = 1; rec nxt; nxt.bx = bbx; nxt.by = bby; nxt.px = cur.bx; nxt.py = cur.by; nxt.path = cur.path + path + b[i]; if (maze[bbx][bby] == 'T') { if (!flag) ans = nxt.path,flag=1; else { if ((nxt.path).size() < ans.size() ) { ans = nxt.path; } } } que.push(nxt); } } } } if (flag) return ans; else { ans = "Impossible."; return ans; } } int main() { while (cin >> n >> m&&!(n == 0 && m == 0)) { for (int i = 0; i < n; i++) scanf("%s", maze[i]); parse(); printf("Maze #%d\n", ++cas); string ans = bfs(); cout << ans << endl << endl; } return 0; }