洛谷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
1 #include <iostream> 2 #include <cstdio> 3 #include <queue> 4 using namespace std; 5 6 #define rep(i,l,r) for(i=l;i<=r;i++) 7 #define read scanf 8 #define change(x,y,z,k) (struct node){x,y,z,k} 9 10 const int maxn=51; 11 12 int array[maxn][maxn]; 13 int n,m,sx,sy,ex,ey; 14 char location; 15 bool vis[maxn][maxn][4]; 16 17 struct node{ 18 int x,y,pos; 19 int g; 20 }; 21 22 /*弄一个数据类 23 N 0 24 E 1 25 S 2 26 W 3 27 */ 28 29 bool change_able(int x,int y){ 30 int res=0; 31 if(array[x][y+1])res++; 32 if(array[x+1][y])res++; 33 if(array[x+1][y+1])res++; 34 if(array[x][y])res++; 35 return res>=1?false:true; 36 } 37 38 void bfs(){ 39 queue<node> q; 40 int tmp; 41 node head; 42 if(location==‘N‘)tmp=0; 43 if(location==‘E‘)tmp=1; 44 if(location==‘S‘)tmp=2; 45 if(location==‘W‘)tmp=3; 46 q.push(change(sx,sy,tmp,0)); 47 while(!q.empty()){ 48 head=q.front(); 49 q.pop(); 50 if(head.x-1<0 || head.y-1<0 || head.x+1>n || head.y+1>m)continue; 51 if(!change_able(head.x,head.y))continue; 52 if(head.x==ex && head.y==ey){cout<<head.g;return;} 53 if(vis[head.x][head.y][head.pos])continue; 54 vis[head.x][head.y][head.pos]=true; 55 q.push(change(head.x,head.y,(head.pos+1)%4,head.g+1)); 56 q.push(change(head.x,head.y,(head.pos-1+4)%4,head.g+1)); 57 if(head.pos==0 && head.x-1>=0)q.push(change(head.x-1,head.y,head.pos,head.g+1)); 58 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)); 59 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)); 60 61 if(head.pos==1 && head.y+1<=m)q.push(change(head.x,head.y+1,head.pos,head.g+1)); 62 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)); 63 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)); 64 65 if(head.pos==2 && head.x+1<=n)q.push(change(head.x+1,head.y,head.pos,head.g+1)); 66 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)); 67 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)); 68 69 if(head.pos==3 && head.y-1>=0)q.push(change(head.x,head.y-1,head.pos,head.g+1)); 70 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)); 71 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)); 72 } 73 cout<<-1; 74 } 75 76 int main(){ 77 cin>>n>>m; 78 int i,j,d; 79 rep(i,1,n) 80 rep(j,1,m) 81 read("%d",&array[i][j]); 82 read("%d%d%d%d %c",&sx,&sy,&ex,&ey,&location); 83 memset(vis,false,sizeof(vis)); 84 bfs(); 85 return 0; 86 }