是搜索play的第四弹!
机器人搬重物
题目描述
机器人移动学会(RMI)现在正尝试用机器人搬运物品。机器人的形状是一个直径 \(1.6\) 米的球。在试验阶段,机器人被用于在一个储藏室中搬运货物。储藏室是一个 \(N\times M\) 的网格,有些格子为不可移动的障碍。机器人的中心总是在格点上,当然,机器人必须在最短的时间内把物品搬运到指定的地方。机器人接受的指令有:
- 向前移动 \(1\) 步(
Creep
); - 向前移动 \(2\) 步(
Walk
); - 向前移动 \(3\) 步(
Run
); - 向左转(
Left
); - 向右转(
Right
)。
每个指令所需要的时间为 \(1\) 秒。请你计算一下机器人完成任务所需的最少时间。
输入格式
第一行为两个正整数 \(N,M\ (1\le N,M\le50)\),下面 \(N\) 行是储藏室的构造,\(0\) 表示无障碍,\(1\) 表示有障碍,数字之间用一个空格隔开。接着一行有 \(4\) 个整数和 \(1\) 个大写字母,分别为起始点和目标点左上角网格的行与列,起始时的面对方向(东 \(\tt E\),南 \(\tt S\),西 \(\tt W\),北 \(\tt N\)),数与数,数与字母之间均用一个空格隔开。终点的面向方向是任意的。
输出格式
一个整数,表示机器人完成任务所需的最少时间。如果无法到达,输出 \(-1\)。
样例 #1
样例输入 #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
样例输出 #1
12
解法&&个人感想
这题是少有的一遍过的绿题吧 果然搜索的绿题比较好做?
几个坑点:
1.机器人是有直径的 所以对于一个格子要把周围的四个格点都标记成不能走
2.需要看样例发现左右上下都要缩小一个单位
3.vis代表走到x,y时朝向dir的vis
4.在循环三步时 如果不能走直接break 如果只是走过可以瞬移
#include<bits/stdc++.h> #define ll long long using namespace std; char di; int n,m,sx,sy,sdir,fx,fy; int ma[55][55];//ma跑的是格点 注意我们只要将所谓的格子转化成格点就可以 int vis[55][55][5]; struct node{int x,y,dir,t; }; queue<node>q; int dx[7]={0,-1,0,1,0,0,0},dy[7]={0,0,1,0,-1,0,0}; bool check(int x,int y){if(x>=1&&x<=n-1&&y>=1&&y<=m-1&&!ma[x][y]) return true;else return false; }//现在要养成check函数的好习惯 int main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){scanf("%d",&ma[i][j]);if(ma[i][j]==1){ma[i-1][j]=1;ma[i][j-1]=1;ma[i-1][j-1]=1;}//打标记}}scanf("%d %d %d %d ",&sx,&sy,&fx,&fy);cin>>di;if(di=='N') sdir=1;if(di=='E') sdir=2;if(di=='S') sdir=3;if(di=='W') sdir=4;//判断方向q.push(node{sx,sy,sdir,0});vis[sx][sy][sdir]=1;while(!q.empty()){int ax=q.front().x,ay=q.front().y,adir=q.front().dir,at=q.front().t;q.pop();if(ax==fx&&ay==fy){printf("%d",at);system("pause");return 0;}int tx=ax,ty=ay;for(int i=1;i<=3;i++){tx+=dx[adir],ty+=dy[adir];if(!check(tx,ty)) break;if(vis[tx][ty][adir]) continue;vis[tx][ty][adir]=1;q.push(node{tx,ty,adir,at+1});}//循环三步走int tdir=adir;tdir--;if(tdir==0) tdir=4;if(check(ax,ay)&&!vis[ax][ay][tdir]){vis[ax][ay][tdir]=1;q.push(node{ax,ay,tdir,at+1});} int kdir=adir;kdir++;if(kdir==5) kdir=1;if(check(ax,ay)&&!vis[ax][ay][kdir]){vis[ax][ay][kdir]=1;q.push(node{ax,ay,kdir,at+1});}//转向}cout<<-1;system("pause");return 0; }