POJ - 1475 Pushing Boxes

题意:推箱子的题目,求最短的路径,如果推的最短一样的话,就算上走的最短

思路:首先我们记录状态:箱子的位置和人的位置,我们先BFS箱子的最短,然后我们可以通过推的方向得到人的位置,然后再BFS人是否能到这里的最短路

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
const int MAXN = 50;

struct status{
	int person_x,person_y;
	int box_x,box_y;
	string ans;
}p,q;
struct node{
	int x,y;
	string ans;
}P,Q;
int dx[]={1, -1, 0, 0};
int dy[]={0, 0, 1, -1};
char Pm[]={'s', 'n', 'e', 'w'};
char Pb[]={'S', 'N', 'E', 'W'};
int visP[MAXN][MAXN],visB[MAXN][MAXN];
char G[MAXN][MAXN];
int sx,sy,ex,ey,bx,by;
int r,c;

int check(int x, int y){
	if (x >= 0 && x< r && y >= 0 && y < c)
		return true;
	return false;
}

int bfs2(int start_x, int start_y, int end_x, int end_y){
	memset(visP, 0, sizeof(visP));
	P.x = start_x;
	P.y = start_y;
	P.ans = "";
	visP[P.x][P.y] = 1;
	visP[p.box_x][p.box_y] = 1;
	queue<node> qq;
	qq.push(P);
	while (!qq.empty()){
		P = qq.front();
		qq.pop();
		if (P.x == end_x && P.y == end_y)
			return true;
		for (int i = 0; i < 4; i++){
			int nx = P.x + dx[i];
			int ny = P.y + dy[i];
			if (check(nx, ny) && G[nx][ny] != '#' && !visP[nx][ny]){
				visP[nx][ny] = 1;
				Q.ans = P.ans + Pm[i];
				Q.x = nx;
				Q.y = ny;
				qq.push(Q);
			}
		}
	}
	return false;
}

int bfs(){
	memset(visB, 0, sizeof(visB));
	p.person_x = sx;
	p.person_y = sy;
	p.box_x = bx;
	p.box_y = by;
	p.ans = "";
	visB[bx][by] = 1;
	queue<status> st;
	st.push(p);
	while (!st.empty()){
		p = st.front();
		st.pop();
		for (int i = 0; i < 4; i++){
			int nx = p.box_x + dx[i];
			int ny = p.box_y + dy[i];
			int tx = p.box_x - dx[i];
			int ty = p.box_y - dy[i];
			if (check(tx, ty) && G[tx][ty] != '#' && check(nx, ny) &&
					G[nx][ny] != '#' && !visB[nx][ny]){
				if (bfs2(p.person_x, p.person_y, tx, ty)){
					visB[nx][ny] = 1;
					q.person_x = p.box_x;
					q.person_y = p.box_y;
					q.box_x = nx;
					q.box_y = ny;
					q.ans = p.ans+P.ans+Pb[i];
					if (nx == ex && ny == ey)
						return true;
					st.push(q);
				}
			}
		}
	}
	return false;
}

int main(){
	int cas = 1;
	while (scanf("%d%d", &r, &c) != EOF && r+c){
		for (int i = 0; i < r; i++){
			scanf("%s", G[i]);
			for (int j = 0; j < c; j++){
				if (G[i][j] == 'S'){
					sx = i;
					sy = j;
				}
				if (G[i][j] == 'T'){
					ex = i;
					ey = j;
				}
				if (G[i][j] == 'B'){
					bx = i;
					by = j;
				}
			}
		}
		printf("Maze #%d\n", cas++);
		if (bfs())
			printf("%s\n", q.ans.c_str());
		else printf("Impossible.\n");
		printf("\n");
	}
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值