机器人搬重物
时间限制(普通/Java) :
1000 MS/ 3000 MS 运行内存限制 : 65536 KByte
总提交 : 33 测试通过 : 13
总提交 : 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");
}