题目描述
机器人移动学会(RMI)现在正尝试用机器人搬运物品。机器人的形状是一个直径 1.6 米的球。在试验阶段,机器人被用于在一个储藏室中搬运货物。储藏室是一个 N × M 的网格,有些格子为不可移动的障碍。机器人的中心总是在格点上,当然,机器人必须在最短的时间内把物品搬运到指定的地方。机器人接受的指令有:
- 向前移动 1 步(
Creep
); - 向前移动 2 步(
Walk
); - 向前移动 3 步(
Run
); - 向左转(
Left
); - 向右转(
Right
)。
每个指令所需要的时间为 1 秒。请你计算一下机器人完成任务所需的最少时间。
第一行为两个正整数 N,M (1≤N,M≤50),下面 N 行是储藏室的构造,0 表示无障碍,1 表示有障碍,数字之间用一个空格隔开。接着一行有 4 个整数和 1 个大写字母,分别为起始点和目标点左上角网格的行与列,起始时的面对方向(东E,南S,西 W,北 N),数与数,数与字母之间均用一个空格隔开。终点的面向方向是任意的。
一个整数,表示机器人完成任务所需的最少时间。如果无法到达,输出 -1。
正文
这道题的各种操作时间代价都是一秒,因此BFS就可以啦
请注意!
- 机器人有体积,check函数中将左上左下右上右下判断一遍就可以啦
- 机器人不能穿墙因此在判断走两三格时判断要加上途径每一格的判断
#include<bits/stdc++.h>
using namespace std;
const int N = 52;
int mp[N][N],n,m,sx,sy,ex,ey,dir,vis[N][N][4],cnt;
char d;
int dx[4] = {0,-1,0,1},dy[4] = {1,0,-1,0};//位移数组
struct node{
int x,y,sum,di;
};
queue<node> q;
// 检查该点合法性
bool check(node t) {return t.x+1<=n && t.x>=1 && t.y>=1 && t.y+1<=m && mp[t.x][t.y] && mp[t.x+1][t.y] && mp[t.x][t.y+1] && mp[t.x+1][t.y+1];}
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
memset(vis,0x3f,sizeof(vis));
cin>>n>>m;
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) {cin>>mp[i][j];mp[i][j] = 1-mp[i][j];}
cin>>sx>>sy>>ex>>ey>>d;
if(d=='S') dir = 3;
if(d=='E') dir = 0;
if(d=='N') dir = 1;
if(d=='W') dir = 2;//对应上方位移数组
q.push(node{sx,sy,0,dir});
while(!q.empty()){
node t = q.front();
q.pop();
if(t.x==ex && t.y==ey) {cout<<t.sum;return 0;}
//五行超长判断,分别为走一格,两格,三格,右转,调头
if(check(node{t.x+dx[t.di],t.y+dy[t.di],0,0}) && vis[t.x+dx[t.di]][t.y+dy[t.di]][t.di]>t.sum+1) q.push(node{t.x+dx[t.di],t.y+dy[t.di],t.sum+1,t.di}),vis[t.x+dx[t.di]][t.y+dy[t.di]][t.di] = t.sum+1;
if(check(node{t.x+dx[t.di],t.y+dy[t.di],0,0}) && check(node{t.x+2*dx[t.di],t.y+2*dy[t.di],0,0}) && vis[t.x+2*dx[t.di]][t.y+2*dy[t.di]][t.di]>t.sum+1) q.push(node{t.x+2*dx[t.di],t.y+2*dy[t.di],t.sum+1,t.di}),vis[t.x+2*dx[t.di]][t.y+2*dy[t.di]][t.di] = t.sum+1;
if(check(node{t.x+dx[t.di],t.y+dy[t.di],0,0}) && check(node{t.x+2*dx[t.di],t.y+2*dy[t.di],0,0}) && check(node{t.x+3*dx[t.di],t.y+3*dy[t.di],0,0}) && vis[t.x+3*dx[t.di]][t.y+3*dy[t.di]][t.di]>t.sum+1) q.push(node{t.x+3*dx[t.di],t.y+3*dy[t.di],t.sum+1,t.di}),vis[t.x+3*dx[t.di]][t.y+3*dy[t.di]][t.di] = t.sum+1;
if(vis[t.x][t.y][(t.di+1)%4]>t.sum+1) q.push(node{t.x,t.y,t.sum+1,(t.di+1)%4}),vis[t.x][t.y][(t.di+1)%4] = t.sum+1;
if(vis[t.x][t.y][(t.di+3)%4]>t.sum+1) q.push(node{t.x,t.y,t.sum+1,(t.di+3)%4}),vis[t.x][t.y][(t.di+1)%4] = t.sum+1;
}
cout<<-1;//无解,即所有状态均不能到达
return 0;
}
标签:node,洛谷,di,sum,重物,vis,dx,dy,P1126
From: https://www.cnblogs.com/OrangeRED/p/18621056