洛谷P1126 机器人搬重物

题目描述

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

输入格式:

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

输出格式:

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

输出样例:

12

思路:

这道题坑真多QAQ 输入是格子图 要转化为点阵 另外机器人有直径 注意不能越界 障碍物周围的四个点全部不能走 代码比较长 还要处理转弯.......

#include<iostream>
#include<cstring>
using namespace std;
int n,m,x1,x2,y1,y2,vis[51][51],dirs,minn=0x7ffffff,ans[1001]={-1},tot;
char dir;
int f[5][2]={{0,0},{0,1},{0,-1},{1,0},{-1,0}}; 
bool a,map[55][55];
struct ljq {
	int x,
	    y,
	    dir,
	    step;
}q[5001];//定义结构体 x y 为当前坐标 dir为所对方向 step为步数
int h=1,t;//队头队尾
int main()
{
    cin>>n>>m;
	for(int i=1; i<=n; i++)
	{
		for(int j=1; j<=m; j++)
		{
			cin>>a;..输入
			if(a==1)
			{
				map[i-1][j-1]=1;
				map[i-1][j]=1;
				map[i][j-1]=1;
				map[i][j]=1;//把格子图转化为点阵 障碍物周围的点标记为1
			}
		}
	}
	for(int i=1; i<=n; i++)
	{
		map[n][i]=1;
		map[i][m]=1;//将边界标记成1
	}
	cin>>x1>>y1;
	cin>>x2>>y2;
	cin>>dir;//输入
	q[++t].x=x1;
	q[t].y=y1;
	q[t].step=0;//初始化搜索
	if(dir=='E')
	{
		q[t].dir=1;
	}
	else if(dir=='W')
	{
		q[t].dir=2;
	}
	else if(dir=='S')
	{
		q[t].dir=3;
	}
	else if(dir=='N')
	{
		q[t].dir=4;//方向变成数字
	}
	memset(vis,999999,sizeof(vis));把最优解数组置为较大的数
	while(h<=t)//广搜开始
	{
		if(q[h].x==x2&&q[h].y==y2)
		{
			ans[++tot]=q[h].step;//如果满足条件 
		}
		for(int i=1;i<=4;i++)//四个方向
		{
			int dirs=q[h].step;
			if(i!=q[h].dir) //如果方向不同 步数+1;
			{
				dirs=q[h].step+1;
				if(i==1&&q[h].dir==2||i==2&&q[h].dir==1||i==3&&q[h].dir==4||i==4&&q[h].dir==3)//如果需要向后转 步数+2
				{
					dirs=q[h].step+2;
				}
			}
			for(int j=1;j<=3;j++)//前进1或2或3格
		    {
			    int lx=q[h].x+j*f[i][0];//目标点坐标
				int ly=q[h].y+j*f[i][1];
			    if(lx>n||lx<1||ly>m||ly<=0||map[lx][ly])//如果进入边界或碰到障碍物 循环停止
			    {
			    	break;
				}
				if(dirs<vis[lx][ly])//最优解
				{
					q[++t].x=lx;q[t].y=ly;//下一个点的坐标
					q[t].step=dirs+1; q[t].dir=i;
					vis[lx][ly]=dirs;
				}
		    }
		}
		h++;
	}
	for(int i=1;i<=tot;i++)
	{
		if(ans[i]<minn)
		{
			minn=ans[i];//答案
		}
	}
	if(minn<0x7ffffff) cout<<minn;//如果minn发生改变 有答案 输出minn
	else cout<<-1;//无答案输出-1
	return 0;
}

蒟蒻一只......题解写的不太好......

猜你喜欢

转载自blog.csdn.net/ljqmiao_/article/details/81126792