【洛谷P1126】機器人搬重物
阿新 • • 發佈:2019-01-09
題目大意:給定一個 N 行,M 列的地圖,一個直徑為 1.6 的圓形機器人需要從起點走到終點,每秒鐘可以實現:向左轉,向右轉,向前 1-3 步。求從起點到終點最少要多長時間。
題解:相比於普通的走迷宮問題,這道題的物體有了體積,最佳的解決方式是選定一個參考點,比如只看這個有體積的機器人的左上角代表整個機器人,那麼就不需要修改整個地圖,且判斷也會很方便。
程式碼如下
#include <bits/stdc++.h> using namespace std; const int maxn=60; const int inf=0x3f3f3f3f; const int dx[]={-1,0,1,0}; const int dy[]={0,1,0,-1}; int n,m,stx,sty,edx,edy,direction; int mp[maxn][maxn],d[maxn][maxn][4]; char s[2]; struct node{ int x,y,dir; }; inline int getdir(char ch){ return ch=='N'?0:ch=='E'?1:ch=='S'?2:3; } void read_and_parse(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&mp[i][j]); scanf("%d%d%d%d%s",&stx,&sty,&edx,&edy,s); direction=getdir(s[0]); } queue<node> q; inline bool check(int x,int y){ if(mp[x][y]||mp[x+1][y]||mp[x][y+1]||mp[x+1][y+1])return 0; if(x<=0||x>=n||y<=0||y>=m)return 0; return 1; } int bfs(){ memset(d,0x3f,sizeof(d)); d[stx][sty][direction]=0,q.push(node{stx,sty,direction}); while(q.size()){ int x=q.front().x,y=q.front().y,dir=q.front().dir;q.pop(); if(x==edx&&y==edy)return d[edx][edy][dir]; for(int i=1;i<=3;i++){ int xx=x+dx[dir]*i,yy=y+dy[dir]*i; if(!check(xx,yy))break; if(d[xx][yy][dir]!=inf)continue; d[xx][yy][dir]=d[x][y][dir]+1,q.push(node{xx,yy,dir}); } if(d[x][y][(dir+1)%4]==inf)d[x][y][(dir+1)%4]=d[x][y][dir]+1,q.push(node{x,y,(dir+1)%4}); if(d[x][y][(dir+3)%4]==inf)d[x][y][(dir+3)%4]=d[x][y][dir]+1,q.push(node{x,y,(dir+3)%4}); } return -1; } void solve(){ printf("%d\n",bfs()); } int main(){ read_and_parse(); solve(); return 0; }