Total Submissions: 82 (18 users) Accepted: 28 (14 users)
[ My Solution ]
推箱子是个家喻户晓的游戏, 相信在大家小的时候都一定玩过。当然, 我们在这里还是做个简单介绍, 如下图所示, 游戏玩家初始站在地图的某个位置, 游戏目标是将图中的箱子全部移往目的地(下图’X’的位置), 每次移动只能选择上下左右方向上某个方向移动一格, 若移动的方向上有箱子存在, 则箱子也往相同的方向移动一格, 并且, 在移动过程中, 玩家(和箱子)不能穿越(或停留于)箱子、障碍物(下图树的位置)和边界区域的位置。除此之外, 为了尽可能的得到最高分, 玩家还应该以尽可能少的步数完成任务。
为了简化问题, 现在, 给你一个地图, 且地图上的游戏者、箱子和目的地都各只有一个, 你需要求出最少需要多少步才能完成任务呢?
输入的第一行有2个整数n, m (2 <= n, m <= 30), 接下来有n行, 每行有m个只由'.' , '*' , 'P', 'B', 'E' 构成的字符, 其中, ‘.’表示可通行区域, '*' 表示障碍物, 'P'表示玩家, 'B'表示箱子, 'E'表示目的地, 输入保证字符'P', 'B', 'E'各只有一个。
若无法完成任务, 则输出-1, 否则输出的第一行有一个数字n, 表示将箱子移至目的地的最少步数, 第二行有n个字符, 表示玩家的移动步骤, 其中'L'表示左移, 'R'表示右移, 'U'表示上移, 'D'表示下移。(若存在多种满足题意的方案, 则任意一组答案都可以通过本题)
6 7
...*...
.*.*.*.
.*...*.
.*.**..
.****B*
.....EP
26
LLLLLLUUUUURRDDRRUURRDDDLD
这是一道SPECIAL JUDGE的题目, 每组数据, 时限1s
/*
这道题不难的,搞了我两天了。状态搜索,采用状态记录的方法,就可以过了
*/
#include<iostream>
#include<string>
#include<cstdio>
#include<queue>
#include<algorithm>
#define manx 30*30*30*31
using namespace std;
struct node{
int x,y;
int bx,by;
int temp;
int num; ////前一个状态地址
}que[manx];
int sx,sy,bx,by,ex,ey,n,m,a,b;
bool s[31][31][31][31]; ////所有状态
char mp[31][31];
void init(){
a=0; b=-1;
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
if(mp[i][j]=='*') continue;
for(int r=1;r<=n;++r){
for(int k=1;k<=m;++k)
s[i][j][r][k]=0;
}
}
}
}
void judge(int x,int y,int bx,int by,char str,int temp){
if(x<1||x>n || y<1||y>m || mp[x][y]=='*') return;
if(x==bx && y==by){
if(str=='U') bx--;
if(str=='D') bx++;
if(str=='L') by--;
if(str=='R') by++;
if(bx<1||bx>n || by<1||by>m || mp[bx][by]=='*') return;
}
if(s[x][y][bx][by]) return;
s[x][y][bx][by]=1;
node te;
te.x=x; te.y=y;
te.bx=bx; te.by=by;
te.temp=temp;
te.num =a-1;////连接
que[++b]=te;
}
void PN (node te){
string str;
while(te.num>=0){
node p = que[te.num];
if(p.x==te.x){
if(p.y-te.y>0) str+='L'; ///left
else str+='R'; ///right
}
if(p.y==te.y){
if(p.x>te.x) str+='U'; ///up
else str+='D'; /// down
}
te = p;
}
for(int i=str.size()-1; i>=0; i--)
cout<<str[i];
cout<<endl;
}
void bfs(){
node te;
te.x=sx; te.y=sy;
te.bx=bx; te.by=by;
te.temp=0;
te.num = -1;
que[++b]=te;
// cout<<a<<" "<<b<<endl;
while(a<=b){
te=que[a];
++a;
if(te.bx==ex && te.by==ey){
printf("%d\n",te.temp);
PN(te);
return ;
}
judge(te.x+1, te.y, te.bx, te.by, 'D', te.temp+1);//xiang xia
judge(te.x-1, te.y, te.bx, te.by, 'U', te.temp+1);//xiang shang
judge(te.x, te.y+1, te.bx, te.by, 'R', te.temp+1);//xiang you
judge(te.x, te.y-1, te.bx, te.by, 'L', te.temp+1);//xiang zuo
}
printf("-1\n");
}
int main(){
while(scanf("%d%d",&n,&m)!=EOF){
for(int i=1;i<=n;++i){
scanf("%s",mp[i]+1);
for(int j=1;j<=m;++j){
if(mp[i][j]=='B'){ bx=i,by=j; }
if(mp[i][j]=='E'){ ex=i,ey=j; }
if(mp[i][j]=='P'){ sx=i,sy=j; }
}
}
init();
s[sx][sy][bx][by]=1;
bfs();
}
}