poj1475 Pushing Boxes

题目链接: http://poj.org/problem?id=1475
这题有个降级版,题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1254
降级版题解链接: http://blog.csdn.net/xzw777_/article/details/78013944
然后我就在之前的代码上加了600+代码就过了,代码如下:

#include<stdio.h>
#include<iostream>
#include<cstring>
#include<string>
#include<queue>
#define N 21
using namespace std;


struct box
{
	int bx,by,px,py,step;
	string sbox;
};
struct people
{
	int x,y;
	string sp;
};


char s[N][N];
int m,n,map[N][N];
bool vis[N][N][4],vv[N][N];
int sx,sy; //箱子起始位置 
int spx,spy; //人起始位置 
int zd[4][2]={-1,0,0,1,1,0,0,-1}; //上右下左0123 
char dir[5]="NESW",dirp[5]="nesw";


bool check(int i,int j)
{
	if(i<0||i>=m||j<0||j>=n||map[i][j]==1) return false;
	return true;
}
string pp,ans;
bool cango(int x,int y,int fx,int fy,int bx,int by) //x,y人之前位置,fx,fy人需要要达到的位置 ,bx,by当前箱子的位置 
{
	//基本bfs 
	memset(vv,0,sizeof vv);
	people p;
	p.x=x,p.y=y;
	queue<people> que;
	vv[x][y]=1;
	que.push(p);
	while(!que.empty())
	{
		people tmp=que.front();que.pop();
		if(tmp.x==fx&&tmp.y==fy)
		{
			pp=tmp.sp;
			return true;
		}
		for(int v=0;v<4;v++)
		{
			int i,j;
			i=zd[v][0]+tmp.x,j=zd[v][1]+tmp.y;
			if(!check(i,j)||vv[i][j]||i==bx&&j==by) continue;
			vv[i][j]=1;
			people p;
			p.x=i,p.y=j;
			p.sp=tmp.sp;
			p.sp+=dirp[v];
			que.push(p);
		}
	}
	return false;
}


int bfs()
{
	memset(vis,0,sizeof vis);
	queue<box> que;
	box b;
	b.bx=sx,b.by=sy,b.step=0,b.px=spx,b.py=spy;
	
	que.push(b);
	while(!que.empty())
	{
		box tmp=que.front();que.pop();
		if(map[tmp.bx][tmp.by]==3) return tmp.step;
		for(int v=0;v<4;v++)
		{
			int i,j,pi,pj;
			i=zd[v][0]+tmp.bx,j=zd[v][1]+tmp.by; //下一时刻箱子可达位置 
			pi=zd[(v+2)%4][0]+tmp.bx,pj=zd[(v+2)%4][1]+tmp.by; //人在要推箱子方向的反方向 
			if(!check(i,j)||!check(pi,pj)||vis[i][j][v]) continue;
			pp="";
			if(!cango(tmp.px,tmp.py,pi,pj,tmp.bx,tmp.by)) continue; //人从之前位置不可达当前需要推箱子的位置 
			vis[i][j][v]=1;
			box b;
			b.bx=i,b.by=j,b.step=tmp.step+1,b.px=tmp.bx,b.py=tmp.by;
			b.sbox=tmp.sbox;
			if(pp!="")
			b.sbox+=pp;
			b.sbox+=dir[v];
			que.push(b);
			if(map[i][j]==3)
			{
				ans=b.sbox;
				return b.step;
			}
		}
	}
	return -1;
}


int main()
{
	int p=0;
	while(scanf("%d%d",&m,&n),m||n)
	{
		for(int i=0;i<m;i++)
		{
			scanf("%s",s[i]);
			for(int j=0;j<n;j++)
			{
				if(s[i][j]=='.') map[i][j]=0;
				else if(s[i][j]=='#') map[i][j]=1;
				else if(s[i][j]=='B') map[i][j]=2;
				else if(s[i][j]=='S') map[i][j]=4;
				else if(s[i][j]=='T') map[i][j]=3;
			}
		}
		for(int i=0;i<m;i++)
		for(int j=0;j<n;j++)
		{
			if(map[i][j]==4) spx=i,spy=j;
			else if(map[i][j]==2) sx=i,sy=j;
		}
		map[spx][spy]=0;
		int step=bfs();
		printf("Maze #%d\n",++p);
		if(step==-1) puts("Impossible.");
		else
		cout<<ans<<endl;
		printf("\n");
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值