Robot Navigation

该博客讨论了如何解决机器人在远程星球上探索时的导航问题。通过接收包含FORWARD、TURN LEFT和TURN RIGHT命令的程序来指定机器人路径。地图以网格形式表示,存在危险点需要避开。目标是找到从起点到目标点的最短路径,并计算不同最短路径的数量,后者对1,000,000取模。输入包括网格大小和详细地图描述,输出是最短路径长度及相应最短路径数量。博主建议使用BFS寻找最短路径,然后结合BFS和动态规划计算方案数,同时注意动态规划过程中避免重复计数。" 104469841,9310448,SpringBoot源码解析:模块结构与自动配置探秘,"['Java', 'Spring', 'Spring Boot', '源码分析']

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

Download as PDF

A robot has been sent to explore a remote planet. To specify a path the robot should take, a program is sent each day. The program consists of a sequence of the following commands:

  • FORWARD X: move forward by X units.
  • TURN LEFT: turn left (in place) by 90 degrees.
  • TURN RIGHT: turn right (in place) by 90 degrees.

The robot also has sensor units which allow it to obtain a map of its surrounding area. The map is represented as a grid. Some grid points contain hazards (e.g. craters) and the program must avoid these points or risk losing the robot.

Naturally, if the initial location of the robot, the direction it is facing, and its destination position are known, it is best to send the shortest program (one consisting of the fewest commands) to move the robot to its destination (we do not care which direction it faces at the destination). You are more interested in knowing the number of different shortest programs that can move the robot to its destination. However, the number of shortest programs can be very large, so you are satisfied to compute the number as a remainder modulo 1,000,000.

Input

There will be several test cases in the input. Each test case will begin with a line with two integers


N M


Where N is the number of rows in the grid, andM is the number of columns in the grid ( 2$ \le$N,M$ \le$100). The nextN lines of input will have M characters each. The characters will be one of the following:

  • `.' Indicating a navigable grid point.
  • `*' Indicating a crater (i.e. a non-navigable grid point).
  • `X' Indicating the target grid point. There will be exactly one `X'.
  • `N', `E', `S', or `W' Indicating the starting point and initial heading of the robot. There will be exactly one of these. Note that the directions mirror compass directions on a map: `N' is North (toward the top of the grid), `E' is East (toward the right of the grid), `S' is South (toward the bottom of the grid) and `W' is West (toward the left of the grid).

There will be no spaces and no other characters in the description of the map. The input will end with a line with two0's.

Output

For each test case, output two integers on a single line, with a single space between them. The first is the length of a shortest possible program to navigate the robot from its starting point to the target, and the second is the number of different programs of that length which will get the robot to the target (modulo 1,000,000). If there is no path from the robot to the target, output two zeros separated by a single space. Output no extra spaces, and do not separate answers with blank lines.

Sample Input

5 6
*....X
.....*
.....*
.....*
N....*
6 5
....X
.****
.****
.****
.****
N****
3 3
.E.
***
.X.
0 0

Sample Output

6 4
3 1
0 0

 

先BFS出最短路径,再BFS+动态规划求出方案数。

 

DP时注意去重。

 

#include<cstdio>
#include<cstring>
#include<queue>

using namespace std;

#define Min(a,b) (a<b?a:b)

const int MAXN=200;

int num[4][MAXN][MAXN];
int Hash[4][MAXN][MAXN];
int d[4][MAXN][MAXN];

char ch[MAXN][MAXN];

int st_x,st_y,st_up,la_x,la_y;
int N,M;
int _min;
struct Node{
	int x,y,up;

};

queue<Node> Map;

int OK_(int x,int y)
{
	if(x>=0 && x<N && y>=0 && y<M)
		return 1;
	return 0;
}

void BFS()
{
	int i,j,up,cnt;
	Node tmp,base,top;

	tmp.x=st_x;	tmp.y=st_y;	tmp.up=st_up;
	memset(num,-1,sizeof(num));
	num[tmp.up][tmp.x][tmp.y]=0;

	while(!Map.empty())
		Map.pop();

	Map.push(tmp);

	while(!Map.empty())
	{
		base=Map.front();	Map.pop();
		//		printf("%d %d %d %d\n",base.x,base.y,base.up,num[base.up][base.x][base.y]);
		up=(base.up+1)%4;
		if(num[up][base.x][base.y]==-1)
		{
			tmp.up=up;	tmp.x=base.x;	tmp.y=base.y;
			Map.push(tmp);
			num[tmp.up][tmp.x][tmp.y]=num[base.up][base.x][base.y]+1;
//			printf("x=%d y=%d up=%d num=%d-->x=%d y=%d up=%d num=%d\n",base.x,base.y,base.up,num[base.up][base.x][base.y],tmp.x,tmp.y,tmp.up,num[tmp.up][tmp.x][tmp.y]);
		}
		up=(base.up-1);
		if(up<0)
			up+=4;
		if(num[up][base.x][base.y]==-1)
		{
			tmp.up=up;	tmp.x=base.x;	tmp.y=base.y;
			Map.push(tmp);
			num[tmp.up][tmp.x][tmp.y]=num[base.up][base.x][base.y]+1;
//			printf("x=%d y=%d up=%d num=%d-->x=%d y=%d up=%d num=%d\n",base.x,base.y,base.up,num[base.up][base.x][base.y],tmp.x,tmp.y,tmp.up,num[tmp.up][tmp.x][tmp.y]);
		}

		if(base.up==1)
		{
			cnt=1;
			while(OK_(base.x,base.y+cnt) && num[base.up][base.x][base.y+cnt]==-1 &&
				(ch[base.x][base.y+cnt]=='.'||ch[base.x][base.y+cnt]=='X'))
			{
				num[base.up][base.x][base.y+cnt]=num[base.up][base.x][base.y]+1;
				tmp.up=base.up;	tmp.x=base.x;	tmp.y=base.y+cnt;
				Map.push(tmp);
//				printf("x=%d y=%d up=%d num=%d-->x=%d y=%d up=%d num=%d\n",base.x,base.y,base.up,num[base.up][base.x][base.y],tmp.x,tmp.y,tmp.up,num[tmp.up][tmp.x][tmp.y]);
				cnt++;
			}
		}
		if(base.up==2)
		{
			cnt=1;
			while(OK_(base.x+cnt,base.y) && num[base.up][base.x+cnt][base.y]==-1 &&
				(ch[base.x+cnt][base.y]=='.'||ch[base.x+cnt][base.y]=='X'))
			{
				num[base.up][base.x+cnt][base.y]=num[base.up][base.x][base.y]+1;
				tmp.up=base.up;	tmp.x=base.x+cnt;	tmp.y=base.y;
				Map.push(tmp);
//				printf("x=%d y=%d up=%d num=%d-->x=%d y=%d up=%d num=%d\n",base.x,base.y,base.up,num[base.up][base.x][base.y],tmp.x,tmp.y,tmp.up,num[tmp.up][tmp.x][tmp.y]);
				cnt++;
			}
		}
		if(base.up==3)
		{
			cnt=1;
			while(OK_(base.x,base.y-cnt) && num[base.up][base.x][base.y-cnt]==-1 &&
				(ch[base.x][base.y-cnt]=='.'||ch[base.x][base.y-cnt]=='X'))
			{
				num[base.up][base.x][base.y-cnt]=num[base.up][base.x][base.y]+1;
				tmp.up=base.up;	tmp.x=base.x;	tmp.y=base.y-cnt;
				Map.push(tmp);
//				printf("x=%d y=%d up=%d num=%d-->x=%d y=%d up=%d num=%d\n",base.x,base.y,base.up,num[base.up][base.x][base.y],tmp.x,tmp.y,tmp.up,num[tmp.up][tmp.x][tmp.y]);
				cnt++;
			}
		}

		if(base.up==0)
		{
			cnt=1;
			while(OK_(base.x-cnt,base.y) && num[base.up][base.x-cnt][base.y]==-1 &&
				(ch[base.x-cnt][base.y]=='.'||ch[base.x-cnt][base.y]=='X'))
			{
				num[base.up][base.x-cnt][base.y]=num[base.up][base.x][base.y]+1;
				tmp.up=base.up;	tmp.x=base.x-cnt;	tmp.y=base.y;
				Map.push(tmp);
//				printf("x=%d y=%d up=%d num=%d-->x=%d y=%d up=%d num=%d\n",base.x,base.y,base.up,num[base.up][base.x][base.y],tmp.x,tmp.y,tmp.up,num[tmp.up][tmp.x][tmp.y]);
				cnt++;
			}
		}
	}
}

void D_BFS()
{
	int i,j,k,up,cnt;
	Node tmp,base,top;

	while(!Map.empty())
		Map.pop();

	memset(Hash,0,sizeof(Hash));

	tmp.up=st_up;	tmp.x=st_x;	tmp.y=st_y;
	Map.push(tmp);

	Hash[tmp.up][tmp.x][tmp.y]=1;

	memset(d,0,sizeof(d));
	d[tmp.up][tmp.x][tmp.y]=1;
	while(!Map.empty())
	{
		base=Map.front();	Map.pop();
		if(num[base.up][base.x][base.y]>_min)
			return ;

		up=(base.up+1)%4;
		if(num[up][base.x][base.y]==num[base.up][base.x][base.y]+1)
		{
			d[up][base.x][base.y]=(d[up][base.x][base.y]+d[base.up][base.x][base.y])%1000000;
			tmp.up=up;	tmp.x=base.x;	tmp.y=base.y;
//			printf("x=%d y=%d up=%d num=%d d=%d-->",base.x,base.y,base.up,num[base.up][base.x][base.y],d[base.up][base.x][base.y]);
//				printf("x=%d y=%d up=%d num=%d d=%d\n",tmp.x,tmp.y,tmp.up,num[tmp.up][tmp.x][tmp.y],d[tmp.up][tmp.x][tmp.y]);
			if(!Hash[tmp.up][tmp.x][tmp.y])
			{
				Hash[tmp.up][tmp.x][tmp.y]=1;
				Map.push(tmp);
				
			}
		}
		up=(base.up-1);
		if(up<0)
			up+=4;
		if(num[up][base.x][base.y]==num[base.up][base.x][base.y]+1)
		{
			d[up][base.x][base.y]=(d[up][base.x][base.y]+d[base.up][base.x][base.y])%1000000;
			tmp.up=up;	tmp.x=base.x;	tmp.y=base.y;
//			printf("x=%d y=%d up=%d num=%d d=%d-->",base.x,base.y,base.up,num[base.up][base.x][base.y],d[base.up][base.x][base.y]);
//				printf("x=%d y=%d up=%d num=%d d=%d\n",tmp.x,tmp.y,tmp.up,num[tmp.up][tmp.x][tmp.y],d[tmp.up][tmp.x][tmp.y]);
			if(!Hash[tmp.up][tmp.x][tmp.y])
			{
				Hash[tmp.up][tmp.x][tmp.y]=1;
				Map.push(tmp);
				
			}
		}

		if(base.up==1)
		{
			cnt=1;
			while(OK_(base.x,base.y+cnt) && (ch[base.x][base.y+cnt]=='.'||ch[base.x][base.y+cnt]=='X') )
			{
				if(num[base.up][base.x][base.y+cnt]==num[base.up][base.x][base.y]+1){
					d[base.up][base.x][base.y+cnt]=(d[base.up][base.x][base.y+cnt]+d[base.up][base.x][base.y])%1000000;
					tmp.up=base.up;	tmp.x=base.x;	tmp.y=base.y+cnt;
//					printf("x=%d y=%d up=%d num=%d d=%d-->",base.x,base.y,base.up,num[base.up][base.x][base.y],d[base.up][base.x][base.y]);
//						printf("x=%d y=%d up=%d num=%d d=%d\n",tmp.x,tmp.y,tmp.up,num[tmp.up][tmp.x][tmp.y],d[tmp.up][tmp.x][tmp.y]);
					if(!Hash[tmp.up][tmp.x][tmp.y])
					{
						Hash[tmp.up][tmp.x][tmp.y]=1;
						Map.push(tmp);
						
					}
				}
				cnt++;
			}
		}
		if(base.up==2)
		{
			cnt=1;
			while(OK_(base.x+cnt,base.y) && (ch[base.x+cnt][base.y]=='.'||ch[base.x+cnt][base.y]=='X') )
			{
				if(num[base.up][base.x+cnt][base.y]== num[base.up][base.x][base.y]+1){
					d[base.up][base.x+cnt][base.y]=(d[base.up][base.x+cnt][base.y]+d[base.up][base.x][base.y])%1000000;
					tmp.up=base.up;	tmp.x=base.x+cnt;	tmp.y=base.y;
//					printf("x=%d y=%d up=%d num=%d d=%d-->",base.x,base.y,base.up,num[base.up][base.x][base.y],d[base.up][base.x][base.y]);
//						printf("x=%d y=%d up=%d num=%d d=%d\n",tmp.x,tmp.y,tmp.up,num[tmp.up][tmp.x][tmp.y],d[tmp.up][tmp.x][tmp.y]);
					if(!Hash[tmp.up][tmp.x][tmp.y])
					{
						Hash[tmp.up][tmp.x][tmp.y]=1;
						Map.push(tmp);
						
					}
				}
				cnt++;
			}
		}
		if(base.up==3)
		{
			cnt=1;
			while(OK_(base.x,base.y-cnt) && (ch[base.x][base.y-cnt]=='.'||ch[base.x][base.y-cnt]=='X'))
			{
				if(num[base.up][base.x][base.y-cnt]==num[base.up][base.x][base.y]+1 ){
					d[base.up][base.x][base.y-cnt]=(d[base.up][base.x][base.y-cnt]+d[base.up][base.x][base.y])%1000000;
					tmp.up=base.up;	tmp.x=base.x;	tmp.y=base.y-cnt;
//					printf("x=%d y=%d up=%d num=%d d=%d-->",base.x,base.y,base.up,num[base.up][base.x][base.y],d[base.up][base.x][base.y]);
//						printf("x=%d y=%d up=%d num=%d d=%d\n",tmp.x,tmp.y,tmp.up,num[tmp.up][tmp.x][tmp.y],d[tmp.up][tmp.x][tmp.y]);
					if(!Hash[tmp.up][tmp.x][tmp.y])
					{
						Hash[tmp.up][tmp.x][tmp.y]=1;
						Map.push(tmp);
						
					}
				}
				cnt++;
			}
		}

		if(base.up==0)
		{
			cnt=1;
			while(OK_(base.x-cnt,base.y) &&	(ch[base.x-cnt][base.y]=='.'||ch[base.x-cnt][base.y]=='X')  )
			{
				if(num[base.up][base.x-cnt][base.y]==num[base.up][base.x][base.y]+1){
					d[base.up][base.x-cnt][base.y]=(d[base.up][base.x-cnt][base.y]+d[base.up][base.x][base.y])%1000000;
					tmp.up=base.up;	tmp.x=base.x-cnt;	tmp.y=base.y;
//					printf("x=%d y=%d up=%d num=%d d=%d-->",base.x,base.y,base.up,num[base.up][base.x][base.y],d[base.up][base.x][base.y]);
//						printf("x=%d y=%d up=%d num=%d d=%d\n",tmp.x,tmp.y,tmp.up,num[tmp.up][tmp.x][tmp.y],d[tmp.up][tmp.x][tmp.y]);
					if(!Hash[tmp.up][tmp.x][tmp.y])
					{
						Hash[tmp.up][tmp.x][tmp.y]=1;
						Map.push(tmp);
						
					}
				}
				cnt++;
			}
		}
	}

}

int main()
{
	int i,j,k;
	int ok,s;
	st_x=-1;st_y=-1;st_up=-1;
	while(scanf("%d%d",&N,&M),N||M)
	{
		for(i=0;i<N;i++)
		{
			scanf("%s",ch[i]);
			for(j=0;j<M;j++)
			{
				if(ch[i][j]=='X')
				{
					la_x=i;	la_y=j;
				}
				else	if(ch[i][j]!='*' && ch[i][j]!='.' )
				{
					st_x=i;	st_y=j;
					if(ch[i][j]=='N')
						st_up=0;
					if(ch[i][j]=='E')
						st_up=1;
					if(ch[i][j]=='S')
						st_up=2;
					if(ch[i][j]=='W')
						st_up=3;
				}
			}
		}
		BFS();
		/*		for(k=0;k<4;k++)
		{
		for(i=0;i<N;i++)
		{
		for(j=0;j<M;j++)
		printf("%d ",num[k][i][j]);
		printf("\n");
		}
		printf("\n");
		}
		*/
		//		printf("OK\n");

		ok=0;
		_min=-1;
		for(i=0;i<4;i++)
		{
			if(num[i][la_x][la_y]!=-1)
			{
				ok=1;
				if(_min==-1)
					_min=num[i][la_x][la_y];
				else
					_min=Min(_min,num[i][la_x][la_y]);
			}
		}
		if(!ok)
		{
			printf("0 0\n");
			continue;
		}
		//		printf("%d ",_min);

		D_BFS();

		s=0;
		for(i=0;i<4;i++)
		{
			if(num[i][la_x][la_y]==_min)
			{
				s=(s+d[i][la_x][la_y])%1000000;
			}
		}
		printf("%d %d\n",_min,s);

	}


	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值