欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

洛谷P1126 机器人搬重物

程序员文章站 2022-06-12 09:37:37
...

题目描述

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

洛谷P1126 机器人搬重物

输入样例:

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;
}

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

相关标签: 广搜