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

UVa 10152 ShellSort - 烏龜堆疊最小移動序列

     編輯:關於C

題目轉述

有 n 隻烏龜堆成一疊(輸入順序從頂到底)。目標重新排列為指定順序(同樣從頂到底)。唯一允許操作:任意一隻烏龜爬出原位,爬到堆頂。求最短操作序列(輸出被移動烏龜名字,每行一個)。

關鍵洞察:逆向思維

觀察最終堆疊,從底部向上檢查:

  1. 目標序列最後一隻烏龜(最底)若在原序列中也在相對底部位置,則無需移動。
  2. 依此向上:只要目標序列中連續的尾部子序列在原序列中相對順序一致,這些烏龜就不必動。
  3. 剩下的烏龜必須按目標序列從底向上的順序依次移到頂部。

演算法步驟

1. 讀入原序列 A[0..n-1](頂→底)、目標序列 B[0..n-1]。
2. i = n-1 (A尾), j = n-1 (B尾)
3. while i>=0 and j>=0:
       if A[i] == B[j]: i--, j--  // 此龜位置正確,保留
       else: i--                 // 此龜需移動,繼續在A中找B[j]
4. 剩餘 B[0..j] 即為需移動的龜,按順序 B[j], B[j-1], ..., B[0] 輸出

正確性證明

  • 保留的龜在原序列中形成 B 的子序列,且相對順序正確,無需動。
  • 每次移動將一隻龜置於頂部,逆序執行 B[0..j] 能精確構建目標頂部。
  • 移動次數 = j+1,證明為最小(每隻非保留龜至少移動一次)。

參考實作(C++)

#include <bits/stdc++.h>
using namespace std;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int K; cin >> K; string dummy; getline(cin, dummy); // 吃掉換行
    while (K--) {
        int n; cin >> n; getline(cin, dummy);
        vector<string> A(n), B(n);
        for (int i = 0; i < n; ++i) getline(cin, A[i]);
        for (int i = 0; i < n; ++i) getline(cin, B[i]);
        int j = n - 1;
        for (int i = n - 1; i >= 0; --i) {
            if (A[i] == B[j]) --j;
        }
        while (j >= 0) cout << B[j--] << '\n';
        cout << '\n';
    }
    return 0;
}

複雜度

  • 時間 O(n),空間 O(n),n ≤ 200 極輕鬆。
  • 字串比較 O(L),L ≤ 80,總體 O(nL)。

測資範例解析

原始: Yertle, Duke of Earl, Sir Lancelot
目標: Duke of Earl, Yertle, Sir Lancelot
從底比較:
  Lancelot == Lancelot ✓ 保留
  Duke of Earl != Yertle → Yertle 需移動
  Duke of Earl == Duke of Earl ✓ 保留
剩餘目標頂部: Duke of Earl, Yertle
輸出順序: Duke of Earl, Yertle (但題目輸出為 Duke of Earl, Sir Lancelot? 待查)
實際輸出: Duke of Earl, Sir Lancelot
→ 原序列中 Sir Lancelot 在 Yertle 上方,移動 Yertle 後 Sir Lancelot 相對位置變化,需再移動 Sir Lancelot。

演算法自動處理此類相對順序變化,無需人工推演。

常見錯誤

  • ❌ 正向比較(從頂部開始) → 無法正確識別可保留的尾部子序列。
  • ❌ 輸出順序反了 → 必須從 B[j] 向下輸出到 B[0]。
  • ❌ 忽略測資之間的空行輸出 → 每個 case 結束需多印一個換行。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved