机器人搬重物

题目:

Description

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

Input

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

Output

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


思路:

  • map:记录是否能走
  • flag:记录当前状态是否出现
  • dir:记录向四个方向走横纵坐标的变化
  • a:当前坐标向左向右转分别代表的数字
  • 0——N,1——W,2——S,3——E
    现将格图转换为点图(自己画图模拟),输入的障碍坐标应为点图的左上角,此时要将余下3个点标为假,起点和终点的坐标都要+1
 void change(int i,int j)
{
	map[i][j]=false; 
	map[i+1][j]=map[i][j+1]=map[i+1][j+1]=false;
}
 void init()
{
	memset(map,1,sizeof(map));
	scanf("%d%d",&n,&m);
	int a;
	char b;
	for (int i=1; i<=n; i++)
		for (int j=1; j<=m; j++)
		{
			scanf("%d",&a);
			if (a) change(i,j); 
		}
	cin>>sx>>sy>>ex>>ey>>b;
	sx++; sy++; ex++; ey++;
	if (b=='N') f[1].d=0;
	else if (b=='W') f[1].d=1;
	else if (b=='S') f[1].d=2;
	else f[1].d=3;//判断机器人起点时的面向方向
}
 BFS中判断是否到达终点,到达立即输出。先改变机器人的面向方向,加入队列;再枚举走的步数。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int N=55;
 struct ss
{
	int x,y,d,ans;
}f[N*N*5];
bool map[N][N],flag[N][N][N];
int n,m,sx,sy,ex,ey;
int dir[4][2]={{-1,0},{0,-1},{1,0},{0,1}};
int a[3][4]={{0,1,2,3},{1,2,3,0},{3,0,1,2}};

 void change(int i,int j)
{
	map[i][j]=false; 
	map[i+1][j]=map[i][j+1]=map[i+1][j+1]=false;
}
 void init()
{
	memset(map,1,sizeof(map));
	scanf("%d%d",&n,&m);
	int a;
	char b;
	for (int i=1; i<=n; i++)
		for (int j=1; j<=m; j++)
		{
			scanf("%d",&a);
			if (a) change(i,j); 
		}
	cin>>sx>>sy>>ex>>ey>>b;
	sx++; sy++; ex++; ey++;
	if (b=='N') f[1].d=0;
	else if (b=='W') f[1].d=1;
	else if (b=='S') f[1].d=2;
	else f[1].d=3;
}
 bool pd(int i,int j)
{
	if (i<=1||i>n||j<=1||j>m) return false;
	return true;
}
 void bfs()
{
	int l=0,r=1;
	f[1].x=sx; f[1].y=sy; f[1].ans=0;
	while (l<r)
	{
		l++;
		if (f[l].x==ex&&f[l].y==ey)
		{
			printf("%d\n",f[l].ans); return;
		}
		int xx,yy,di;
		for (int i=1; i<=2; i++) 
		{
			di=a[i][f[l].d];
			if (!flag[f[l].x][f[l].y][di])
			{
				flag[f[l].x][f[l].y][di]=true;
				r++;
				f[r].x=f[l].x; f[r].y=f[l].y; f[r].ans=f[l].ans+1; f[r].d=di;
			}
		}
		for (int i=1; i<=3; i++)
		{
			xx=f[l].x+i*dir[f[l].d][0];
			yy=f[l].y+i*dir[f[l].d][1];
			if (map[xx][yy]&&pd(xx,yy))
			{
				if (!flag[xx][yy][f[l].d])
				{
					flag[xx][yy][f[l].d]=true;
					r++; 
					f[r].x=xx; f[r].y=yy; f[r].ans=f[l].ans+1; f[r].d=f[l].d;
				}
			}
			else break;
		}
	}
	printf("-1\n");
}
 int main()
{
	init();
	bfs();
	return 0;
}
原文地址:https://www.cnblogs.com/lyxzhz/p/11405024.html