luogu p1126 机器人搬重物

原题链接:
机器人搬重物 - 洛谷https://www.luogu.com.cn/problem/P1126

题目描述

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

输入格式

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

输出格式

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

Solution:

        我感觉很不错的bfs题,要注意的细节挺多的

        1.起点和终点可能重合,所以我这里直接在出队的时候判断是否与终点重合,无须特判

        2.标记数组记得带方向(方向类bfs题必备的嘛)

        3.如果走一步的时候有障碍,第二步没障碍了,也是不能走的!!一定要停止走!

        4.也是最重要的,机器人是占位4格!给的坐标是左上角坐标!所以一定要判断右,下,右下三格格子是否碰到障碍物

这里我先预处理出每个方向左转右转后是哪个方向,并且每个方向往前走坐标该怎么动,然后简单的bfs就okk啦

ACcode:

#include<bits/stdc++.h>
using namespace std;
char lft[129];
char rht[129];
int runx[4][129];
int runy[4][129];
int ma[55][55];
int vis[55][55][127];
int n,m;
int endx,endy;
struct node{
	int x,y,step;
	char fx;
	node(){}
	node(int x1,int y1,int step1,char ch):x(x1),y(y1),step(step1),fx(ch){}
};
node beginn;
int main()
{
	rht['E'] = 'S',rht['S'] = 'W',rht['W'] = 'N',rht['N'] = 'E';
	lft['E'] = 'N',lft['N'] = 'W',lft['W'] = 'S',lft['S'] = 'E';
	for(int i = 1;i<=3;++i)
	{
		runx[i]['E'] = runx[i]['W'] = 0,runx[i]['N'] = -i,runx[i]['S'] = i;
		runy[i]['N'] = runy[i]['S'] = 0,runy[i]['E'] = i,runy[i]['W'] = -i;
	}
	queue<node>	q;
	cin>>n>>m;
	for(int i = 1;i<=n;++i)
		for(int j = 1;j<=m;++j)
			cin>>ma[i][j];
	cin>>beginn.x>>beginn.y>>endx>>endy>>beginn.fx;
	beginn.step = 0;
	q.push(beginn);
	while(!q.empty())
	{
		int xx = q.front().x;
		int yy = q.front().y;
		int stepp = q.front().step;
		char fx = q.front().fx;
		q.pop();
		if(vis[xx][yy][fx])	continue;
		vis[xx][yy][fx] = 1;
		if(xx==endx&&yy==endy){
			cout<<stepp<<endl;
			return 0;
		}
		char nfx = lft[fx];
		if(!vis[xx][yy][nfx])	
			q.push(node(xx,yy,stepp+1,nfx));	
		nfx = rht[fx];
		if(!vis[xx][yy][nfx])	
			q.push(node(xx,yy,stepp+1,nfx));
		for(int i = 1;i<=3;++i){
			int xxx = xx+runx[i][fx];
			int yyy = yy+runy[i][fx];
			if(xxx<=0||yyy<=0||xxx>n||yyy>m||ma[xxx][yyy]==1||ma[xxx+1][yyy]==1||ma[xxx][yyy+1]==1||ma[xxx+1][yyy+1]==1)	break;
			if(xxx+1>n||yyy+1>m)	break;
			if(vis[xxx][yyy][fx])	continue;	
			q.push(node(xxx,yyy,stepp+1,fx));
		}
	}
	cout<<-1<<endl;
	return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值