有 n 隻烏龜堆成一疊(輸入順序從頂到底)。目標重新排列為指定順序(同樣從頂到底)。唯一允許操作:任意一隻烏龜爬出原位,爬到堆頂。求最短操作序列(輸出被移動烏龜名字,每行一個)。
觀察最終堆疊,從底部向上檢查:
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] 輸出
#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]。