CSU-1975 機器人搬重物(BFS)
1975: 機器人搬重物
Time Limit: 1 Sec Memory Limit: 128 Mb Submitted: 64 Solved: 10
Description
機器人移動學會(RMI)現在正嘗試用機器人搬運物品。機器人的形狀是一個直徑1.6米的球。在試驗階段,機器人被用於在一個儲藏室中搬運貨物。儲藏室是一個N*M的網格,有些格子為不可移動的障礙。機器人的中心總是在格點上,當然,機器人必須在最短的時間內把物品搬運到指定的地方。機器人接受的指令有:向前移動1步(Creep);向前移動2步(Walk);向前移動3步(Run);向左轉(Left);向右轉(Right)。每個指令所需要的時間為1秒。請你計算一下機器人完成任務所需的最少時間。
Input
輸入的第一行為兩個正整數N,M(N,M<=50),下面N行是儲藏室的構造,0表示無障礙,1表示有障礙,數字之間用一個空格隔開。接著一行有四個整數和一個大寫字母,分別為起始點和目標點左上角網格的行與列,起始時的面對方向(東E,南S,西W,北N),數與數,數與字母之間均用一個空格隔開。終點的面向方向是任意的。
Output
一個整數,表示機器人完成任務所需的最少時間。如果無法到達,輸出-1。
Sample Input
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
Sample Output
12
Hint
Source
機器人搬重物
題意:給你一個圖,讓你求出機器人從一個點到另一個點需要的最短時間。乍一看就是普通的BFS求最短路問題。但是有很多坑。。。很多坑。。
①首先機器人是在點上,障礙物是格子,也就是說機器人所在的點周圍的4個格子都不能有障礙物。而且點和格子的坐標對應關系要弄清楚,最好畫個圖。
②然後行走分了方向,其實就是bfs多了兩個選擇,一個左轉一個右轉。
③走的時候有直走1、2、3步三種方式,需要判斷前方有沒有障礙。
思路:進行bfs,直接采用優先隊列,這樣可以確定到達某一點時肯定是最短時間,不會因為轉向什麽的產生影響。
幾個特判的地方要註意:①起點終點一樣,0。②起點或終點在不可移動的地方,-1。
#include<cstdio> #include<queue> #include<cstring> using namespace std; const int maxn=55; char c; int a[maxn][maxn],n,m,sx,sy,ex,ey,sd; int dy[4]={1,0,-1,0}; int dx[4]={0,1,0,-1}; bool vis[maxn][maxn][5]; struct node { int x,y,d,step;//用d(0、1、2、3、4)表示不同朝向 bool operator < (const node &a) const{ return a.step<step; } }; priority_queue<node> q; //queue<node> q; bool check(int x,int y) { if(x>=n||y>=m||x<=0||y<=0) return false; if(a[x][y]==1||a[x+1][y]==1||a[x][y+1]==1||a[x+1][y+1]==1) return false; return true; } void bfs() { memset(vis,false,sizeof(vis)); node now,next; now.x = sx; now.y = sy; now.d = sd; now.step = 0; if(!check(sx,sy)) { printf("-1\n"); return ; } if(!check(ex,ey)) { printf("-1\n"); return ; } while(!q.empty()) q.pop(); q.push(now); vis[sx][sy][sd] = true; while(!q.empty()) { now = q.top(); q.pop(); //printf("%d %d %d %d\n",now.x,now.y,now.d,now.step); if(now.x==ex&&now.y==ey) { printf("%d\n",now.step); return ; } for(int step=1;step<=3;step++) { next.x = now.x+dx[now.d]*step; next.y = now.y+dy[now.d]*step; next.d = now.d; if(check(next.x,next.y)&&vis[next.x][next.y][next.d]==false) { next.step = now.step+1; q.push(next); vis[next.x][next.y][next.d] = true; } else//如果1 2 3某一個不能走,那後面的肯定不能走 { break; } } if(vis[now.x][now.y][(now.d+1)%4]==false)//óò×a { next.x = now.x; next.y = now.y; next.d = (now.d+1)%4; next.step = now.step+1; q.push(next); vis[next.x][next.y][next.d] = true; } if(vis[now.x][now.y][(now.d-1+4)%4]==false)//×ó×a { next.x = now.x; next.y = now.y; next.d = (now.d-1+4)%4; next.step = now.step+1; q.push(next); vis[next.x][next.y][next.d] = true; } } printf("-1\n"); } int main() { while(scanf("%d %d",&n,&m)!=EOF) { for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { scanf("%d\n",&a[i][j]); } } scanf("%d %d %d %d",&sx,&sy,&ex,&ey); getchar(); scanf("%c",&c); if(sx==ex&&sy==ey) { printf("0\n"); continue; } if(c==‘E‘) sd=0; else if(c==‘S‘) sd=1; else if(c==‘W‘) sd=2; else if(c==‘N‘) sd=3; bfs(); } }
CSU-1975 機器人搬重物(BFS)