leetcode 909. 爬坡和梯子(BFS)
阿新 • • 發佈:2018-11-21
題目:
現在有一個數組如下:
36 35 34 33 32 31 25 26 27 28 29 30 24 23 22 21 20 19 13 14 15 16 17 18 12 11 10 09 08 07 01 02 03 04 05 06
每一次可以移動1至6格,然後某些位置還可能有梯子,梯子直達某些位置,現在在左下角,求最少移動次數,到右上角。
思路:
這題最噁心的地方就是,題目的輸入和實際輸入是反了的,樣例中體現的思維是第一行,然而輸入的資料第N-1行變成了第一行,即上下顛倒了。
求最少移動次數到某一個地方,就是一個簡單的bfs,每次把當前的位置輸入進來,然後有幾種轉移方式,分別都加入佇列即可。
需要加一個數組記錄當前位置的最小次數,如果從佇列中拿出一個位置,這個位置之前已經來過並且之前用的次數比這次少,那麼就可以continue,這樣減小狀態數。還可以有效去除迴圈。
程式碼:
class Solution { public: int N; int d[500]; int getrow(int num){ int aa = num/N; if(num%N!=0)aa++; return aa; } int getcol(int num){ int aa = num%N; int bb = num/N; if(aa==0)bb--; aa = (aa+N-1)%N+1; if(bb%2==0){ return aa; } else{ return N-aa+1; } } struct MY{ int x,stp; MY(){} MY(int a,int b):x(a),stp(b){} }; int snakesAndLadders(vector<vector<int> >& board) { N = board.size(); queue<MY>qu; memset(d,-1,sizeof(d)); qu.push(MY(1,0)); while(!qu.empty()){ MY mm = qu.front();qu.pop(); if(d[mm.x]!=-1&&mm.stp>=d[mm.x])continue; if(d[mm.x]==-1)d[mm.x] = mm.stp; if(mm.x>=N*N){ return mm.stp; } for(int i=1;i<=6;i++){ int row = getrow(mm.x+i); int col = getcol(mm.x+i); if(mm.x+i>N*N)continue; if(board[N-row][col-1]!=-1&&board[N-row][col-1]<=N*N)qu.push(MY(board[N-row][col-1],mm.stp+1)); else { qu.push(MY(mm.x+i,mm.stp+1)); } } } return -1; } };
我這份程式碼寫的有些多餘,我把每一個數字對應的行和列都算了出來,然後根據行列算梯子。