您的位置:首页 > 其它

P1126 机器人搬重物

2018-02-01 12:54 225 查看
题目描述

机器人移动学会(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。



输入输出样例

输入样例#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

输出样例#1: 复制

12

解析:

这题注意几个点:

1.机器人有体积,且以左上角为真正位置(x,y)



所以,障碍物碰撞判断为:

G[ x ][ y ] || G[ x + 1 ][ y ] || G[ x ][ y + 1 ] || G[ x + 1 ][ y + 1 ]

2.坐标及方向需要一起hash一下,判重

3.左转右转的写法为:(逆时针为例)

temp.f = ( f + 3 ) % 4 ; //左转

temp.f = ( f + 1 ) % 4 ; //右转

上代码:

bfs

#include<bits/stdc++.h>
using namespace std;
const int dy[ 4 ] = { 0, 1, 0, -1 }, dx[ 4 ] = { -1, 0, 1, 0 } ;        //每个方向的移动规则
int n, m, G[ 60 ][ 60 ] ;
bool vis[ 20000 ] ; //记录访问过的位置
inline int has( int a, int b, int c )
{
return c * 2700 + a * 51 + b ;   //返回每种情况唯一对应的hash值
}
struct pos   //每个位置的信息
{
int x, y ;  //坐标
int f ; //方向
int step ; //已移动时间
} ;
queue<pos> que ;
inline bool check( int x, int y )    //判断是否撞上障碍物
{
if( G[ x ][ y ] || G[ x + 1 ][ y ] || G[ x ][ y + 1 ] || G[ x + 1 ][ y + 1 ] )
return 1 ;
return 0 ;
}
inline void bfs()
{
int x, y, ex, ey, f, d, step, tx, ty ;
char c ;
scanf("%d %d %d %d %c", &x, &y, &ex, &ey, &c );
switch( c )
{
case 'N':
f = 0 ;
break ;
case 'E':
f = 1 ;
break ;
case 'S':
f = 2 ;
break ;
case 'W':
f = 3 ;
break ;
}
pos temp ;
temp.x = x, temp.y = y, temp.f = f, temp.step = 0 ;
que.push( temp ) ;
while( !que.empty() )
{
temp = que.front() ;
que.pop() ;
x = temp.x, y = temp.y, f = temp.f, d = has( x, y, f ), step = temp.step ;
if( x == ex && y == ey )   //判断是否是重点
{
printf("%d",step) ;
exit( 0 ) ;
}
if( vis[ d ] ) //判断是否被访问过
continue ;
vis[ d ] = 1 ;
temp.step ++ ;
temp.f =(f+3)%4; //左转
que.push(temp);
temp.f =(f+1)%4; //右转
que.push(temp);
temp.f =f;
//1,2,3步都去跳
for(int i=1;i<=3;i++)
{
tx = x + dx[ f ] * i, ty = y + dy[ f ] * i ;
if( tx <= 0 || ty <= 0 || tx >= n || ty >= m || check( tx, ty ) )
break ;//小步数都跳不了的话,直接pass,没必要走大步数
temp.x = tx ;
temp.y = ty ;
que.push( temp ) ;
}
}
printf("-1");
}
int main()
{
scanf("%d %d", &n, &m ) ;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d", &G[ i ][ j ] );
bfs() ;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: