P1126 机器人搬重物 题解

题目描述

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

输入格式

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

输出格式

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

解题思路
其实这道题还好,但是要注意:边缘地带是不能走的,还有,有障碍的话,四个格点都不能走。当再走较小步数的时候发现已经有障碍的话,直接终止行走。
代码:(C++)

#include <bits/stdc++.h>
using namespace std;
int n, m, bx, by, ex, ey;
int moved[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
int maped[55][55];
int vis[55][55][4];
char dire;

map < char , int > di;

struct node
{
	int step;
	int x, y;
	int num;
};

int turn_left(int x)
{
	int td = x + 1;
	if(td > 4) td = 1;
	return td;
}

int turn_right(int x)
{
	int td = x - 1;
	if(td < 1) td = 4;
	return td;
}

void change(int x, int y, int num)
{
	if(num)
	{
		maped[x][y] = -1;
		maped[x - 1][y - 1] = -1;
		maped[x - 1][y] = -1;
		maped[x][y - 1] = -1;
	}
	return;
}

void init()
{
	cin >> n >> m;
	for(int i = 1;i <= n;i++)
		for(int j = 1;j <= m;j++)
		{
			int cx;
			cin >> cx;
			change(i, j, cx);
		}
	cin >> bx >> by >> ex >> ey >> dire;
}

void bfs()
{
	queue < node > q;
	node fx;
	fx.num = di[dire];
	fx.step = 0;
	fx.x = bx;
	fx.y = by;
	q.push(fx);
	while(!q.empty())
	{
	 	node x = q.front();
	 	q.pop();
	 	for(int i = 1;i <= 3;i++)
	 	{
	 		int tx = x.x + moved[x.num - 1][0] * i;
	 		int ty = x.y + moved[x.num - 1][1] * i;
	 		if(tx > 0 && ty > 0 && tx < n && ty < m && maped[tx][ty] != -1 && vis[tx][ty][x.num - 1] == 0)
			{
			  	node y;
			  	y.x = tx;
			  	y.y = ty;
			  	y.num = x.num;
			  	y.step = x.step + 1;
			  	vis[tx][ty][y.num - 1] = 1;
			  	q.push(y);
			  	if(y.x == ex && y.y == ey)
			  	{
			  		cout << y.step << endl;
			  		exit(0);
				}
			} 
			else if(maped[tx][ty] == -1) break;
		}
		node y;
	  	y.x = x.x;
	  	y.y = x.y;
	  	y.num = turn_left(x.num);
		if(vis[y.x][y.y][y.num - 1] == 0)
		{
			y.step = x.step + 1;
	  		q.push(y);
	  		vis[y.x][y.y][y.num - 1] = 1;
	  		y.step--;
		}	
	  	y.num = turn_right(x.num);
	  	if(vis[y.x][y.y][y.num - 1] == 0)
	  	{
	  		y.step = x.step + 1;
	  		q.push(y);
	  		vis[y.x][y.y][y.num - 1] = 1;
	  		y.step--;
		}	
	}
}

int main()
{
	di.insert(make_pair('S', 1));
	di.insert(make_pair('E', 2));
	di.insert(make_pair('N', 3));
	di.insert(make_pair('W', 4));
	init();
	if(bx == ex && by == ey)
	{
		cout << 0 << endl;
		return 0;
	}
	bfs();
	cout << -1 << endl;
	return 0;
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值