机器人搬重物

  • 比赛描述

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

 #include<iostream>  
using namespace std;  

int dx[4]={0,1,0,-1};  
int dy[4]={1,0,-1,0};  

int map[56][56],nmap[56][56];  
int m,n,min,bi,bj,ei,ej,d;  
int stp[56][56][56],mins;  
bool p;  

int toward(char c)  
{  
    if(c=='E')  
        return 0;  
    if(c=='S')  
        return 1;  
    if(c=='W')  
        return 2;  
    if(c=='N')  
        return 3;  
    return 0;  
}  

int main()  
{  
    int i,k,j;  
    scanf("%d%d",&m,&n);  
    for(i=1;i<=m;i++)  
        for(j=1;j<=n;j++)  
            scanf("%d",&map[i][j]);  
    for(i=1;i<=m-1;i++)  
    {  
        for(j=1;j<=n-1;j++)  
        {  
            if(map[i][j]==0&&map[i][j+1]==0&&map[i+1][j]==0&&map[i+1][j+1]==0)    
                nmap[i][j]=1;  
        }  
    }  
    scanf("%d%d%d%d",&bi,&bj,&ei,&ej);  
    getchar();  
    char ch=getchar();  
    d=toward(ch);  
    ///////////////////////////////  
    for(i=0;i<m;i++)  
        for(j=0;j<n;j++)  
            for(k=0;k<4;k++)  
                stp[i][j][k]=10000;  
    ////////////////////////////////  
    if(nmap[bi][bj])  
    {  
        stp[bi][bj][d]=0;  
        p=true;  
    }  
    while(p)  
    {  
        p=false;  
        for(i=1;i<m;i++)  
            for(j=1;j<n;j++)  
                for(k=0;k<4;k++)  
                    if(nmap[i][j]&&stp[i][j][k]<10000)  
                    {  
                        if(nmap[i+dx[k]][j+dy[k]])  
                        {  
                            if(stp[i+dx[k]][j+dy[k]][k]>stp[i][j][k]+1)  
                            {  
                                stp[i+dx[k]][j+dy[k]][k]=stp[i][j][k]+1;  
                                p=true;  
                            }  
                            if(nmap[i+2*dx[k]][j+2*dy[k]])  
                            {  
                                if(stp[i+2*dx[k]][j+2*dy[k]][k]>stp[i][j][k]+1)  
                                {  
                                    stp[i+2*dx[k]][j+2*dy[k]][k]=stp[i][j][k]+1;  
                                    p=true;  
                                }  
                                if(nmap[i+3*dx[k]][j+3*dy[k]])  
                                    if(stp[i+3*dx[k]][j+3*dy[k]][k]>stp[i][j][k]+1)  
                                    {  
                                        stp[i+3*dx[k]][j+3*dy[k]][k]=stp[i][j][k]+1;  
                                        p=true;  
                                    }  
                            }  
                        }  
                        if(stp[i][j][(k+1)%4]>stp[i][j][k]+1)  
                        {  
                            stp[i][j][(k+1)%4]=stp[i][j][k]+1;  
                            p=true;  
                        }  
                        if(stp[i][j][(k+3)%4]>stp[i][j][k]+1)  
                        {  
                            stp[i][j][(k+3)%4]=stp[i][j][k]+1;  
                            p=true;  
                        }  
                    }  
    }  
    mins=10000;  
    for(k=0;k<4;k++)  
    {  
        if(mins>stp[ei][ej][k])  
            mins=stp[ei][ej][k];  
    }  
    if(mins==10000)  
    {  
        cout<<"-1"<<endl;  
    }  
    else   
        cout<<mins<<endl;  
    return 0;  
}  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值