杭电 1245

推箱子:

http://acm.hdu.edu.cn/showproblem.php?pid=1254


bfs+dfs

记不清是哪个题来着,用的类似的方法,用广搜确定两点之间的距离,然后用深搜搜答案。应该是1044这道题吧。


少加了一个剪枝,然后各种超时


#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
bool map[10][10][5];
int d[4][2]={-1,0,0,-1,1,0,0,1};
int maze[10][10],b[10][10];
int tx,ty,px,py;

struct node
{
	int bx,by;
	int px,py;
	int step;
}cur,tmp;
bool flag;
int ax,ay;
int n,m;
node start;
int enx,eny;
bool dfs(int x,int y)//人从x,y能到目的地不(箱子的下边),用bfs也可以,不过用dfs能少些代码
{
	if(x==tx && y==ty)
		return 1;
	if(x<0|| x>=n ||y<0 || y>=m)
		return 0;
	if(x==ax && y==ay) //箱子挡住了
		return 0;
	if(b[x][y]==1)
		return 0;
	b[x][y]=1;
	return dfs(x+1,y) ||dfs(x-1,y) ||dfs(x,y+1) ||dfs(x,y-1);
}
int res;
queue<node>qu;
void bfs()
{
	start.step=0;
	while(!qu.empty()) qu.pop();
	//queue<node>qu;
	qu.push(start);
	//node cur,tmp;
	while(!qu.empty())
	{
		cur=qu.front();  qu.pop();
		if(cur.bx==enx && cur.by==eny)
		{
			flag=true;
			res=cur.step;
			return;
		}
		for(int i=0;i<4;i++)
		{
			tmp.bx=cur.bx+d[i][0];
			tmp.by=cur.by+d[i][1];//下一个箱子的位置
			//原来箱子的位置;
			ax=cur.bx;
			ay=cur.by;
			//人要到的位置
			tx=cur.bx-d[i][0];
			ty=cur.by-d[i][1];
			//原来人的位置
			tmp.px=cur.px;
			tmp.py=cur.py;
			tmp.step=cur.step+1;
			if(tmp.bx>=0&&tmp.bx<n && tmp.by>=0&&tmp.by<m && 
				maze[tmp.bx][tmp.by]!=1 &&!map[tmp.bx][tmp.by][i])//这少加了个剪枝。。。太粗心了
			{
				memcpy(b,maze,sizeof(maze));
				if(tx>=0&&tx<n && ty>=0&&ty<m && maze[tx][ty]!=1 &&
					dfs(tmp.px,tmp.py))//人能到达箱子的后方
				{//这块的if纯粹就是个鸡肋,有没有一个样,都是15ms
					if(tmp.bx==enx && tmp.by==eny)
					{
						flag=1;
						res=tmp.step;
						return ;
					}
					tmp.px=tx,tmp.py=ty;
					map[tmp.bx][tmp.by][i]=1;
					qu.push(tmp);
				}
			}
		}
	}
}
int main()
{
	int t;
	scanf("%d",&t);
	
		while(t--)
		{
			scanf("%d %d",&n,&m);
			for(int i=0;i<n;i++)
				for(int j=0;j<m;j++)
				{
					scanf("%d",&maze[i][j]);
					if(maze[i][j]==2)//箱子坐标
						start.bx=i,start.by=j;
					else if(maze[i][j]==3)//目标坐标
						enx=i,eny=j;
					else if(maze[i][j]==4)//人的坐标
						start.px=i,start.py=j;
				}
			memset(map,0,sizeof(map));
			flag=0;
			res=0;
			bfs();
			if(flag)
			{
				 printf("%d\n", res); 
			}
			else
				 printf("-1\n");  
		}
	
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值