1. 程式人生 > >leetcode 909. 爬坡和梯子(BFS)

leetcode 909. 爬坡和梯子(BFS)

題目:

現在有一個數組如下:

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;
}



};

我這份程式碼寫的有些多餘,我把每一個數字對應的行和列都算了出來,然後根據行列算梯子。