首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

HDU 1180 詭異的樓梯:BFS 搜索最短時間

     編輯:關於C++

題目大意

M×N (≤ 25) 迷宮,字符:
'.' 路、'*' 牆、'S' 起點、'T' 終點、'-' 橫向樓梯、'|' 縱向樓梯。
樓梯行為:
- 偶數時間:'-' 水平移動,'|' 垂直移動。
- 奇數時間:'-' 垂直移動,'|' 水平移動。
進入樓梯格需 1 時間,若方向匹配則順勢移動到下一格(再 +1 時間?題目實為:進入樓梯格 1 時間,若當前時間奇偶與樓梯朝向匹配,則**同一步**順勢滑出到相鄰非樓梯格,總耗時 1;否須等待(原地 +1 時間)或繞行)。
實際規則:每步 1 時間。進入樓梯格後,若當前時間奇偶允許該方向移動,則**必須**順勢移動到相鄰格(若該格非牆且未訪問),總耗時仍 1;否則可選擇原地等待(+1 時間)或不進入。
求從 S 到 T 最短時間,不可達輸出提示語。

BFS 狀態擴展

狀態:(x, y, time)。訪問標記 vis[x][y](因 BFS 保證首次到達最短,無需記 time 維度)。
從隊首取出,嘗試 4 方向移動:

  1. 目標格為牆或越界 → 跳過。
  2. 目標格為 '.' 或 'T' → 正常入隊,time+1。
  3. 目標格為 '-' 或 '|' → 判斷當前 time 奇偶與樓梯類型:
    - 若匹配(偶數時間 '-' 水平 / '|' 垂直;奇數時間相反):
      計算順勢滑出的目標格 (nx, ny)。
      若滑出格合法且非牆且未訪問 → 入隊滑出格,time+1。
      **注意**:滑出格可能是另一樓梯?題目暗示滑出後停在普通格。
    - 若不匹配:可選擇**原地等待**(入隊當前格,time+1)。

關鍵代碼片段(簡化邏輯)


struct Node { int x, y, t; };
queue q;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};

while (!q.empty()) {
    Node cur = q.front(); q.pop();
    if (cur.x == ex && cur.y == ey) return cur.t;
    for (int dir = 0; dir < 4; ++dir) {
        int nx = cur.x + dx[dir], ny = cur.y + dy[dir];
        if (nx<0||nx>=M||ny<0||ny>=N||map[nx][ny]=='*'||vis[nx][ny]) continue;
        char c = map[nx][ny];
        if (c == '.' || c == 'T') {
            vis[nx][ny] = 1;
            q.push({nx, ny, cur.t+1});
        } else if (c == '-' || c == '|') {
            bool match = (cur.t % 2 == 0) ? (c == '-') : (c == '|'); // 偶數: '-'水平, '|'垂直
            if (match) {
                // 順勢滑出
                int sx = nx + (c=='-' ? 0 : (dir<2?1:-1)); // 簡化:需根據進入方向確定滑出方向
                int sy = ny + (c=='-' ? (dir==0?1:-1) : 0);
                // 實際需嚴格判斷:進入方向決定滑出方向
                // 此處略過詳細邏輯,完整代碼見原文
                if (sx>=0&&sx=0&&sy

完整邏輯細節(參考原文代碼)

  • 進入 '-' 時:若水平進入(dir=0 或 3),偶數時間順勢向右/左滑出一格;若垂直進入,奇數時間順勢向下/上滑出。
  • 進入 '|' 時:若垂直進入(dir=1 或 2),偶數時間順勢向下/上滑出;若水平進入,奇數時間順勢向右/左滑出。
  • 滑出後的目標格必須合法、非牆、未訪問。
  • 等待操作:原地 time+1 入隊。因 BFS 按時間層擴展,同位置不同時刻**不需要**重複訪問(首次到達即最短)。

複雜度

  • 狀態數 ≤ M×N = 625,每狀態 4 方向,極快。

總結

HDU 1180 是帶有**時間相關動態障礙**的 BFS 變體。核心難點在於正確建模樓梯的「奇偶匹配 + 順勢滑出」邏輯,並處理「等待」操作。代碼雖長但邏輯清晰,是狀態空間搜索進階練習好題。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved