题目描述
机器人移动学会(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。
扫描二维码关注公众号,回复:
892936 查看本文章
输入输出样例
输入样例#1:
复制
9 10 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 1 0 7 2 2 7 S
题目不难,但是要注意如果遇到障碍物或者遇到边缘部分,就不能继续走,其他的就用优先队列解决。
#include<cstdio> #include<cstring> #include<iostream> #include<queue> #include<map> using namespace std; struct node { int x,y,time,to;//to的值为1,2,3,4分别代表北,东,南,西方向 bool friend operator<(node c,node d) { return c.time>d.time; } }no,ne; int g[60][60],G[60][60]; int vis_dir[60][60][5];//标记地图上的点是否已用同样的方向走过 int mark[60][60];//标记目的地 int N,M; map<char,int>dir; priority_queue<node>q; char s; void init() { memset(g,0,sizeof(g)); memset(G,0,sizeof(G)); memset(vis_dir,0,sizeof(vis_dir)); memset(mark,0,sizeof(mark)); dir['N']=1; dir['E']=2; dir['S']=3; dir['W']=4; } void transfer()//转换地图 { for(int i=1;i<=N;i++) for(int j=1;j<=M;j++) if(g[i][j]==1) G[i][j]=G[i-1][j]=G[i][j-1]=G[i-1][j-1]=1; } void bfs() { int i,j,k; while(!q.empty()) { no=q.top(); q.pop(); if(mark[no.x][no.y]==-1) { printf("%d\n",no.time); return; } vis_dir[no.x][no.y][no.to]=1; if(no.to%2==1)//如果方向为北或者南,移动x { k=no.to-2;//to=1为北,x往北边移,to=3同理 for(i=k;i!=4*k;i+=k) { ne.y=no.y; ne.x=no.x+i; ne.time=no.time+1; ne.to=no.to; if(ne.x>=0&&ne.x<=N&&!vis_dir[ne.x][ne.y][ne.to]) { if(G[ne.x][ne.y]==1||ne.x==0||ne.x==N)//移动的过程遇到障碍物或者不能移动,终止循环 break; q.push(ne); vis_dir[ne.x][ne.y][ne.to]=1; } } } else//同上 { k=3-no.to; for(i=k;i!=4*k;i+=k) { ne.x=no.x; ne.y=no.y+i; ne.time=no.time+1; ne.to=no.to; if(ne.y>=0&&ne.y<=M&&!vis_dir[ne.x][ne.y][ne.to]) { if(G[ne.x][ne.y]==1||ne.y==0||ne.y==M) break; q.push(ne); vis_dir[ne.x][ne.y][ne.to]=1; } } } for(i=no.to+1;i<=no.to+3;i+=2)//左右换方向 { ne.x=no.x; ne.y=no.y; ne.time=no.time+1; ne.to=i; while(ne.to>4) ne.to-=4; if(!vis_dir[ne.x][ne.y][ne.to]) { q.push(ne); vis_dir[ne.x][ne.y][ne.to]=1; } } } printf("-1\n"); return; } int main() { int i,j; scanf("%d%d",&N,&M); init(); for(i=1;i<=N;i++) for(j=1;j<=M;j++) scanf("%d",&g[i][j]); transfer(); cin>>no.x>>no.y>>i>>j>>s; no.time=0; no.to=dir[s]; mark[i][j]=-1; q.push(no); bfs(); }