您的位置:首页 > 其它

洛谷OJ P1126 机器人搬重物 解题报告

2015-05-14 00:40 218 查看

洛谷OJ P1126 机器人搬重物 解题报告

by MedalPluS

【题目描述】

机器人移动学会(RMI)现在正尝试用机器人搬运物品。机器人的形状是一个直径1.6米的球。在试验阶段,机器人被用于在一个储藏室中搬运货物。储藏室是一个N*M的网格,有些格子为不可移动的障碍。机器人的中心总是在格点上,当然,机器人必须在最短的时间内把物品搬运到指定的地方。机器人接受的指令有:向前移动1步(Creep);向前移动2步(Walk);向前移动3步(Run);向左转(Left);向右转(Right)。每个指令所需要的时间为1秒。请你计算一下机器人完成任务所需的最少时间

【输入格式】

输入的第一行为两个正整数N,M(N,M<=50),下面N行是储藏室的构造,0表示无障碍,1表示有障碍,数字之间用一个空格隔开。接着一行有四个整数和一个大写字母,分别为起始点和目标点左上角网格的行与列,起始时的面对方向(东E,南S,西W,北N),数与数,数与字母之间均用一个空格隔开。终点的面向方向是任意的。

【输出格式】

一个整数,表示机器人完成任务所需的最少时间。如果无法到达,输出-1

【分析】

最近楼主在刷训练场,发现洛谷的一些题目还是很发人深省的

废话不多说,进入解题模式————————

首先,很容易看出是一个BFS的题,但是处理起来会有点麻烦

应该是这样一个图:


然后就是BFS,注意,这里对于一个点判断是否可行要判断(x,y)(x+1,y)(x,y+1)(x+1,y+1) 为什么? 因为对于圆心的坐标即为(x,y)是在左上角,所以应在所在正方形格子中

还有,对于一次性连跳的方式,要注意跳的过程中也要满足,比如说上图,如果先跳2格,再跳2个就有问题了,因为最后一次中经过了黑格子

然后就是简单地BFS,这题细节还是比较多的,楼主考虑了24h左右~

代码code

#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;

#define rep(i,l,r) for(i=l;i<=r;i++)
#define read scanf
#define change(x,y,z,k) (struct node){x,y,z,k}

const int maxn=51;

int array[maxn][maxn];
int n,m,sx,sy,ex,ey;
char location;
bool vis[maxn][maxn][4];

struct node{
int x,y,pos;
int g;
};

/*弄一个数据类
N 0
E 1
S 2
W 3
*/

bool change_able(int x,int y){
int res=0;
if(array[x][y+1])res++;
if(array[x+1][y])res++;
if(array[x+1][y+1])res++;
if(array[x][y])res++;
return res>=1?false:true;
}

void bfs(){
queue<node> q;
int tmp;
node head;
if(location=='N')tmp=0;
if(location=='E')tmp=1;
if(location=='S')tmp=2;
if(location=='W')tmp=3;
q.push(change(sx,sy,tmp,0));
while(!q.empty()){
head=q.front();
q.pop();
if(head.x-1<0 || head.y-1<0 || head.x+1>n || head.y+1>m)continue;
if(!change_able(head.x,head.y))continue;
if(head.x==ex && head.y==ey){cout<<head.g;return;}
if(vis[head.x][head.y][head.pos])continue;
vis[head.x][head.y][head.pos]=true;
q.push(change(head.x,head.y,(head.pos+1)%4,head.g+1));
q.push(change(head.x,head.y,(head.pos-1+4)%4,head.g+1));
if(head.pos==0 && head.x-1>=0)q.push(change(head.x-1,head.y,head.pos,head.g+1));
if(head.pos==0 && head.x-2>=0 && change_able(head.x-1,head.y))q.push(change(head.x-2,head.y,head.pos,head.g+1));
if(head.pos==0 && head.x-3>=0 && change_able(head.x-1,head.y) && change_able(head.x-2,head.y))q.push(change(head.x-3,head.y,head.pos,head.g+1));

if(head.pos==1 && head.y+1<=m)q.push(change(head.x,head.y+1,head.pos,head.g+1));
if(head.pos==1 && head.y+2<=m && change_able(head.x,head.y+1))q.push(change(head.x,head.y+2,head.pos,head.g+1));
if(head.pos==1 && head.y+3<=m && change_able(head.x,head.y+1) && change_able(head.x,head.y+2))q.push(change(head.x,head.y+3,head.pos,head.g+1));

if(head.pos==2 && head.x+1<=n)q.push(change(head.x+1,head.y,head.pos,head.g+1));
if(head.pos==2 && head.x+2<=n && change_able(head.x+1,head.y))q.push(change(head.x+2,head.y,head.pos,head.g+1));
if(head.pos==2 && head.x+3<=n && change_able(head.x+1,head.y) && change_able(head.x+2,head.y))q.push(change(head.x+3,head.y,head.pos,head.g+1));

if(head.pos==3 && head.y-1>=0)q.push(change(head.x,head.y-1,head.pos,head.g+1));
if(head.pos==3 && head.y-2>=0 && change_able(head.x,head.y-1))q.push(change(head.x,head.y-2,head.pos,head.g+1));
if(head.pos==3 && head.y-3>=0 && change_able(head.x,head.y-1) && change_able(head.x,head.y-2))q.push(change(head.x,head.y-3,head.pos,head.g+1));
}
cout<<-1;
}

int main(){
cin>>n>>m;
int i,j,d;
rep(i,1,n)
rep(j,1,m)
read("%d",&array[i][j]);
read("%d%d%d%d %c",&sx,&sy,&ex,&ey,&location);
memset(vis,false,sizeof(vis));
bfs();
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: