南邮 OJ 1583 机器人搬重物

机器人搬重物

时间限制(普通/Java) :  1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 33            测试通过 : 13 

比赛描述

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

输入

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

输出

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



/* AC 9MS
#include<iostream>
#define N 51
int mp[N][N];					//原来的图
int map[N][N];					//处理后的,机器人可走路线图
int dis[N][N][4];
bool vst[N][N][4];
int dirX[4] = { 0, 1, 0,-1};
int dirY[4] = { 1, 0,-1, 0};

int main(){
	freopen("test.txt","r",stdin);
	int n,m,sx,sy,ex,ey,i,j,k,d;
	char dir;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++){
		for(j=1;j<=m;j++){
			scanf("%d",&mp[i][j]);
			for(k=0;k<4;k++){
				dis[i][j][k] = INT_MAX;
			}
		}
	}
	n--;
	m--;
	for(i=1;i<=n;i++){
		for(j=1;j<=m;j++){
			map[i][j] = mp[i][j]|mp[i][j+1]|mp[i+1][j]|mp[i+1][j+1];
		}
	}
	scanf("%d%d%d%d %c",&sx,&sy,&ex,&ey,&dir);
	switch(dir){
		case 'E':
			d = 0;
			break;
		case 'S':
			d = 1;
			break;
		case 'W':
			d = 2;
			break;
		case 'N':
			d = 3;
			break;
	}
	dis[sx][sy][d] = 0;
	bool flag = 1;
	int step;
	while(flag){
		flag = 0;
		for(i=1;i<=n;i++){
			for(j=1;j<=m;j++){
				for(d=0;d<4;d++){
					if((step=dis[i][j][d])!=INT_MAX){
						step++;
						if(dis[i][j][(d+1)%4] > step){
							dis[i][j][(d+1)%4] = step;
							flag = 1;
						}
						if(dis[i][j][(d+3)%4] > step){
							dis[i][j][(d+3)%4] = step;
							flag = 1;
						}
						for(k=1;k<=3;k++){
							sx = i+k*dirX[d];
							sy = j+k*dirY[d];
							if(sx>=1 && sx<=n && sy>=1 && sy<=m){
								if(map[sx][sy]){
									break;
								}else if(dis[sx][sy][d] > step){
									dis[sx][sy][d] = step;
									flag = 1;
								}
							}
						}
					}
				}
			}
		}
	}
	int minV = INT_MAX;
	for(d=0;d<4;d++){
		if(minV > dis[ex][ey][d]){
			minV = dis[ex][ey][d];
		}
	}
	if(minV==INT_MAX){
		printf("-1\n");
	}else{
		printf("%d\n",minV);
	}
}
*/


#include<iostream>
#define N 51
int mp[N][N];					//原来的图
int map[N][N];					//处理后的,机器人可走路线图
int dis[N][N][4];
bool vst[N][N][4];
int dirX[4] = { 0, 1, 0,-1};
int dirY[4] = { 1, 0,-1, 0};

int main(){
	freopen("test.txt","r",stdin);
	int n,m,sx,sy,ex,ey,i,j,k,d;
	char dir;
	scanf("%d%d",&n,&m);
	for(i=1;i<=n;i++){
		for(j=1;j<=m;j++){
			scanf("%d",&mp[i][j]);
			for(k=0;k<4;k++){
				dis[i][j][k] = INT_MAX;
			}
		}
	}
	n--;
	m--;
	for(i=1;i<=n;i++){
		for(j=1;j<=m;j++){
			map[i][j] = mp[i][j]|mp[i][j+1]|mp[i+1][j]|mp[i+1][j+1];
		}
	}
	scanf("%d%d%d%d %c",&sx,&sy,&ex,&ey,&dir);
	switch(dir){
		case 'E':
			d = 0;
			break;
		case 'S':
			d = 1;
			break;
		case 'W':
			d = 2;
			break;
		case 'N':
			d = 3;
			break;
	}
	dis[sx][sy][d] = 0;
	bool flag = 1;
	int step;
	while(flag){
		flag = 0;
		for(i=1;i<=n;i++){
			for(j=1;j<=m;j++){
				for(d=0;d<4;d++){
					if((step=dis[i][j][d])!=INT_MAX){
						step++;
						if(dis[i][j][(d+1)%4] > step){
							dis[i][j][(d+1)%4] = step;
							flag = 1;
						}
						if(dis[i][j][(d+3)%4] > step){
							dis[i][j][(d+3)%4] = step;
							flag = 1;
						}
						for(k=1;k<=3;k++){
							sx = i+k*dirX[d];
							sy = j+k*dirY[d];
							if(sx>=1 && sx<=n && sy>=1 && sy<=m){
								if(map[sx][sy]){
									break;
								}else if(dis[sx][sy][d] > step){
									dis[sx][sy][d] = step;
									flag = 1;
								}
							}
						}
					}
				}
			}
		}
		k = INT_MAX;
		for(d=0;d<4;d++){
			if((step=dis[ex][ey][d]) < k){
				k = step;
			}
		}
		if(k!=INT_MAX){
			printf("%d\n",k);		//Wrong Answer at Test 7 这是一个错误的提前退出,原因不知道
			return 0;
		}
	}
	printf("-1\n");
}




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值