洛谷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; }
相关文章推荐
- 【p1126-机器人搬重物】解题记录
- HDU 2232 机器人的舞蹈 解题报告(高手请无视!)
- 山东省第四届ACM大学生程序设计竞赛解题报告(部分)
- POJ 3468 解题报告
- 【九度OJ】题目1444:More is better 解题报告
- POJ 1838 解题报告
- HDU 5443 The Water Problem 解题报告(如题)
- POJ - 3414 Pots解题报告(输出路径的bfs)
- NOIP2014解方程解题报告
- 北大acm 1061解题报告--欧几里得算法及其应用
- LeetCode 解题报告 Candy
- 2015 亚洲区域赛长春赛区网络赛解题报告(9/13)
- Leetcode 89. Gray Code 格雷码 解题报告
- 【九度OJ】题目1024:畅通工程 解题报告
- [Leetcode] 754. Reach a Number 解题报告
- hdu4679 Terrorist’s destroy 解题报告
- [LeetCode]sqrt(int x)解题报告之二分查找
- 解题报告:HDU_3085 Nightmare Ⅱ BFS
- [Leetcode] 756. Pyramid Transition Matrix 解题报告
- timus 1346. Intervals of Monotonicity URAL 解题报告 DP 小水题,阅读理解