现在的位置: 首页 > 综合 > 正文

hdu 1254 推箱子

2013年08月25日 ⁄ 综合 ⁄ 共 2436字 ⁄ 字号 评论关闭

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

 

Problem Description

 

推箱子是一个很经典的游戏.今天我们来玩一个简单版本.在一个M*N的房间里有一个箱子和一个搬运工,搬运工的工作就是把箱子推到指定的位置,注意,搬运工只能推箱子而不能拉箱子,因此如果箱子被推到一个角上(如图2)那么箱子就不能再被移动了,如果箱子被推到一面墙上,那么箱子只能沿着墙移动.

现在给定房间的结构,箱子的位置,搬运工的位置和箱子要被推去的位置,请你计算出搬运工至少要推动箱子多少格.


 

 

Input

 

输入数据的第一行是一个整数T(1<=T<=20),代表测试数据的数量.然后是T组测试数据,每组测试数据的第一行是两个正整数M,N(2<=M,N<=7),代表房间的大小,然后是一个M行N列的矩阵,代表房间的布局,其中0代表空的地板,1代表墙,2代表箱子的起始位置,3代表箱子要被推去的位置,4代表搬运工的起始位置.
 

 

Output

 

对于每组测试数据,输出搬运工最少需要推动箱子多少格才能帮箱子推到指定位置,如果不能推到指定位置则输出-1.
 

 

Sample Input

 

1 5 5 0 3 0 0 0 1 0 1 4 0 0 0 1 0 0 1 0 2 0 0 0 0 0 0 0
 

 

Sample Output

    4

弄了两个晚上了,终于弄出来了,第一次做没有考虑到人的情况,而且推箱子中,人不会动.然后用搜索,出现莫名奇妙的错误啊...

思路:

用广搜寻找最小步数,但推箱子需要满足以下几个条件:

1.人能走到推箱子的那个位置

2.人不能穿过箱子.

3.箱子可以回到前一状态的位置,但不是同一方向回到的.

AC code:

#include<stdio.h>
#include<cstring>
#include<queue>
#include<iostream>
using namespace std;
#define M 8
int Maze[M][M];
int visited2[M][M][4];
int visited1[M][M];
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};
int row,col;
struct Point
{
	int x,y;
};
struct State
{
	Point Box,People;
	int step;
};
bool check(Point p)
{
  if(p.x<0||p.y<0||p.x>=row||p.y>=col||Maze[p.x][p.y]==1)
  return false;
  return true;
}
bool bfs(Point a,Point b,int x,int y)
{
	memset(visited1,0,sizeof(visited1));
	visited1[a.x][a.y]=1;     //人的位置 
	visited1[x][y]=1;    //箱子的位置 
	queue<Point> Q;
	Q.push(a);
	int k;
	Point current,temp;
	while(!Q.empty())
	{
		current=Q.front();
		Q.pop();
	 if(current.x==b.x&¤t.y==b.y) return true;
	 for(k=0;k<4;++k)
	 {
	  temp.x=current.x+dx[k];
	  temp.y=current.y+dy[k];
	  if(check(temp)&&!visited1[temp.x][temp.y])
	  {
		Q.push(temp);
		visited1[temp.x][temp.y]=1;
	  }
	}
   }
   return false;
}
int main()
{
	int test,sum;
	scanf("%d",&test);
	while(test--)
	{
	 sum=-1;
	 memset(visited2,0,sizeof(visited2));
	 scanf("%d%d",&row,&col);
	 int i,j;
	 Point st,p;
	 for(i=0;i<row;++i)
	 {
	  for(j=0;j<col;++j)
	  {
	  scanf("%d",&Maze[i][j]);
	  if(Maze[i][j]==2)
	  {
		st.x=i;
		st.y=j;
	  }
	  if(Maze[i][j]==4)
	  {
		p.x=i;
		p.y=j;
	  }
	}
    }
	State first,current,temp;
	first.Box.x=st.x;
	first.Box.y=st.y;
	first.People.x=p.x;
	first.People.y=p.y;
	first.step=0;
	queue<State> q;
	q.push(first);
	Point a,b;
	int x,y;
	while(!q.empty())
	{
		current=q.front();
		q.pop();
	if(Maze[current.Box.x][current.Box.y]==3)
	     { sum=current.step;break;}
	for(i=0;i<4;++i)
	{
	 temp.Box.x=current.Box.x+dx[i];
	 temp.Box.y=current.Box.y+dy[i];
	 temp.step=current.step+1;
	 a.x=current.People.x;   a.y=current.People.y;        //a是人的位置 
	 b.x=current.Box.x-dx[i]; b.y=current.Box.y-dy[i];        //b是推箱子的位置 
	 x=current.Box.x;
	 y=current.Box.y;
	 temp.People.x=b.x; 
	temp.People.y=b.y; 
	 if(check(temp.Box)&&check(temp.People)&&!visited2[temp.Box.x][temp.Box.y][i]&&bfs(a,b,x,y))
	 {
		
		q.push(temp);
		visited2[temp.Box.x][temp.Box.y][i]=1;
	 }
	}
    }
    printf("%d\n",sum);
}
}
	 

 

抱歉!评论已关闭.